mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Various
nukkit fixes add new brushes some other minor stuff
This commit is contained in:
parent
733f5eabc4
commit
71071998c6
@ -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);
|
||||
}
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"),
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
178
core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java
Normal file
178
core/src/main/java/com/boydti/fawe/object/brush/ErodeBrush.java
Normal 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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user