mirror of
https://github.com/boy0001/FastAsyncWorldedit.git
synced 2024-11-28 13:45:36 +01:00
Various
Fix biome change not sending packet Add optimized biome get and set (AsyncWorld, EditSession etc.) Add undo for biome changes Fix tile entities for slow (non NMS) bukkit queue Translate some stuff Fix some concurrency issues with autoqueue cuboid region geChunks() now has fixed memory cost (applies to commands e.g. //listchunks) Fix some undo issues
This commit is contained in:
parent
708ac6e03f
commit
ebc7ba43e6
@ -7,7 +7,6 @@ buildscript {
|
||||
dependencies {
|
||||
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.3'
|
||||
classpath 'org.ajoberstar:grgit:1.7.0'
|
||||
// classpath 'it.unimi.dsi:fastutil:7.0.12'
|
||||
}
|
||||
}
|
||||
|
||||
@ -80,9 +79,9 @@ subprojects {
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {url "http://ci.emc.gs/nexus/content/groups/aikar/" }
|
||||
maven {url "http://ci.regularbox.com/plugin/repository/everything/"}
|
||||
maven {url "http://empcraft.com/maven2"}
|
||||
maven {url "http://repo.mcstats.org/content/repositories/public"}
|
||||
maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"}
|
||||
maven {url "http://maven.sk89q.com/repo/"}
|
||||
maven {url "http://nexus.hc.to/content/repositories/pub_releases"}
|
||||
|
@ -37,6 +37,7 @@ apply plugin: 'com.github.johnrengelman.shadow'
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
}
|
||||
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.boydti.fawe.bukkit;
|
||||
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import java.util.HashMap;
|
||||
import org.apache.commons.lang.mutable.MutableInt;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
@ -25,7 +24,6 @@ public class BukkitTaskMan extends TaskManager {
|
||||
}
|
||||
|
||||
public MutableInt index = new MutableInt(0);
|
||||
public HashMap<Integer, Integer> tasks = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void async(final Runnable r) {
|
||||
|
@ -11,10 +11,10 @@ import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.bukkit.BukkitUtil;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
|
||||
@ -75,36 +75,26 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
long start = System.currentTimeMillis();
|
||||
int recommended = 25 + BukkitQueue_All.ALLOCATE;
|
||||
boolean more = true;
|
||||
BukkitQueue_All parent = (BukkitQueue_All) getParent();
|
||||
final BukkitQueue_All parent = (BukkitQueue_All) getParent();
|
||||
final Chunk chunk = getChunk();
|
||||
Object[] disableResult = parent.disableLighting(chunk);
|
||||
final World world = chunk.getWorld();
|
||||
char[][] sections = getCombinedIdArrays();
|
||||
final int bx = getX() << 4;
|
||||
final int bz = getZ() << 4;
|
||||
if (layer == -1) {
|
||||
// Biomes
|
||||
if (layer == 0) {
|
||||
final int[][] biomes = getBiomeArray();
|
||||
final byte[] biomes = getBiomeArray();
|
||||
if (biomes != null) {
|
||||
final LocalWorld lw = BukkitUtil.getLocalWorld(world);
|
||||
final int X = getX() << 4;
|
||||
final int Z = getZ() << 4;
|
||||
final BaseBiome bb = new BaseBiome(0);
|
||||
int last = 0;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
final int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
int index = 0;
|
||||
Vector2D mutable = new Vector2D();
|
||||
for (int z = 0; z < 16; z++) {
|
||||
final int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
if (last != biome) {
|
||||
last = biome;
|
||||
bb.setId(biome);
|
||||
}
|
||||
lw.setBiome(new Vector2D(X + x, Z + z), bb);
|
||||
mutable.z = bx + z;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
mutable.x = bz + x;
|
||||
lw.setBiome(mutable, FaweCache.getBiome(biomes[index++] & 0xFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -142,11 +132,11 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
final byte[] cacheZ = FaweCache.CACHE_Z[layer];
|
||||
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))));
|
||||
if (!checkTime) {
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
final ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (int k = 0; k < 16; k++) {
|
||||
final int l = k << 8;
|
||||
final int y = cacheY[l];
|
||||
Thread thread = new Thread(new Runnable() {
|
||||
final Thread thread = new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (int m = l; m < l + 256; m++) {
|
||||
@ -166,6 +156,13 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
int x = cacheX[m];
|
||||
int z = cacheZ[m];
|
||||
int id = combined >> 4;
|
||||
if (FaweCache.hasNBT(id) && parent.adapter != null) {
|
||||
CompoundTag nbt = getTile(x, y, z);
|
||||
if (nbt != null) {
|
||||
parent.adapter.setBlock(new Location(world, bx + x, y, bz + z), new BaseBlock(id, combined & 0xF, nbt), false);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Block block = chunk.getBlock(x, y, z);
|
||||
setBlock(block, id, (byte) (combined & 0xF));
|
||||
}
|
||||
@ -214,15 +211,14 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
int x = cacheX[j];
|
||||
int z = cacheZ[j];
|
||||
int y = cacheY[j];
|
||||
Block block = chunk.getBlock(x, y, z);
|
||||
if (FaweCache.hasNBT(id) && parent.adapter != null) {
|
||||
CompoundTag tile = getTile(x, y, z);
|
||||
if (tile != null) {
|
||||
BaseBlock baseBlock = new BaseBlock(id, data, tile);
|
||||
parent.adapter.setBlock(block.getLocation(), baseBlock, false);
|
||||
parent.adapter.setBlock(new Location(world, bx + x, y, bz + z), new BaseBlock(id, combined & 0xF, tile), false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Block block = chunk.getBlock(x, y, z);
|
||||
setBlock(block, id, (byte) data);
|
||||
if (light) {
|
||||
parent.disableLighting(disableResult);
|
||||
|
@ -161,11 +161,6 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
return getWorldName() != null ? Bukkit.getWorld(getWorldName()) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(World world, int x, int z) {
|
||||
return world.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {}
|
||||
|
||||
@ -188,15 +183,6 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
return getWorld().getEnvironment() == World.Environment.NORMAL;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(World impWorld, int x, int z, boolean generate) {
|
||||
if (impWorld.loadChunk(x, z, generate)) {
|
||||
keepLoaded.put(MathMan.pairInt(x, z), System.currentTimeMillis());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private volatile boolean timingsEnabled;
|
||||
private static boolean alertTimingsChange = true;
|
||||
private static Field fieldTimingsEnabled;
|
||||
|
@ -3,18 +3,18 @@ package com.boydti.fawe.bukkit.v0;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.ChunkSnapshot;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.Biome;
|
||||
|
||||
public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
|
||||
public class BukkitQueue_All extends BukkitQueue_0<ChunkSnapshot, ChunkSnapshot, ChunkSnapshot> {
|
||||
|
||||
public static int ALLOCATE;
|
||||
private static int LIGHT_MASK = 0x739C0;
|
||||
@ -39,87 +39,108 @@ public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
|
||||
|
||||
@Override
|
||||
public void setHeightMap(FaweChunk chunk, byte[] heightMap) {
|
||||
// Do nothing
|
||||
// Not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyLight(Chunk chunk, int x, int y, int z, int value) {
|
||||
|
||||
public void setSkyLight(ChunkSnapshot chunk, int x, int y, int z, int value) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBlockLight(Chunk chunk, int x, int y, int z, int value) {
|
||||
// chunk.getBlock(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
public int getCombinedId4Data(Chunk section, int x, int y, int z) {
|
||||
Block block = ((Chunk) section).getBlock(x & 15, y, z & 15);
|
||||
int combined = block.getTypeId() << 4;
|
||||
if (FaweCache.hasData(combined)) {
|
||||
combined += block.getData();
|
||||
}
|
||||
return combined;
|
||||
public void setBlockLight(ChunkSnapshot chunk, int x, int y, int z, int value) {
|
||||
// Not supported
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(final Chunk chunk, int x, int y, int z) {
|
||||
if (!chunk.isLoaded()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
chunk.load(true);
|
||||
public int getCombinedId4Data(ChunkSnapshot chunk, int x, int y, int z) {
|
||||
if (chunk.isSectionEmpty(y >> 4)) {
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
int id = chunk.getBlockTypeId(x & 15, y, z & 15);
|
||||
if (FaweCache.hasData(id)) {
|
||||
int data = chunk.getBlockData(x & 15, y, z & 15);
|
||||
return (id << 4) + data;
|
||||
} else {
|
||||
return id << 4;
|
||||
}
|
||||
return chunk.getBlock(x, y, z).getLightFromBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(final Chunk chunk, int x, int y, int z) {
|
||||
if (!chunk.isLoaded()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
chunk.load(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
return chunk.getBlock(x, y, z).getLightFromSky();
|
||||
public int getBiome(ChunkSnapshot chunkSnapshot, int x, int z) {
|
||||
Biome biome = chunkSnapshot.getBiome(x & 15, z & 15);
|
||||
return adapter.getBiomeId(biome);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(final Chunk chunk, int x, int y, int z) {
|
||||
if (!chunk.isLoaded()) {
|
||||
TaskManager.IMP.sync(new RunnableVal<Object>() {
|
||||
@Override
|
||||
public void run(Object value) {
|
||||
chunk.load(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
return chunk.getBlock(x, y, z).getLightLevel();
|
||||
public ChunkSnapshot getSections(ChunkSnapshot chunkSnapshot) {
|
||||
return chunkSnapshot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getCachedSections(World impWorld, int cx, int cz) {
|
||||
return impWorld.getChunkAt(cx, cz);
|
||||
public ChunkSnapshot getCachedChunk(World world, int cx, int cz) {
|
||||
if (world.isChunkLoaded(cx, cz)) {
|
||||
long pair = MathMan.pairInt(cx, cz);
|
||||
Long originalKeep = keepLoaded.get(pair);
|
||||
keepLoaded.put(pair, Long.MAX_VALUE);
|
||||
if (world.isChunkLoaded(cx, cz)) {
|
||||
Chunk chunk = world.getChunkAt(cx, cz);
|
||||
if (originalKeep != null) {
|
||||
keepLoaded.put(pair, originalKeep);
|
||||
} else {
|
||||
keepLoaded.remove(pair);
|
||||
}
|
||||
return chunk.getChunkSnapshot(false, true, false);
|
||||
|
||||
} else {
|
||||
keepLoaded.remove(pair);
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
public int getEmmittedLight(final ChunkSnapshot chunk, int x, int y, int z) {
|
||||
return chunk.getBlockEmittedLight(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSkyLight(final ChunkSnapshot chunk, int x, int y, int z) {
|
||||
return chunk.getBlockSkyLight(x & 15, y, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(final ChunkSnapshot chunk, int x, int y, int z) {
|
||||
x = x & 15;
|
||||
z = z & 15;
|
||||
return Math.max(chunk.getBlockEmittedLight(x, y, z), chunk.getBlockSkyLight(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot loadChunk(World world, int x, int z, boolean generate) {
|
||||
Chunk chunk = world.getChunkAt(x, z);
|
||||
chunk.load(generate);
|
||||
return chunk.isLoaded() ? chunk.getChunkSnapshot(false, true, false) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSnapshot getCachedSections(World impWorld, int cx, int cz) {
|
||||
return getCachedChunk(impWorld, cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(ChunkSnapshot chunk, int x, int y, int z) {
|
||||
if (adapter == null) {
|
||||
return null;
|
||||
}
|
||||
Location loc = new Location(getWorld(), x, y, z);
|
||||
BaseBlock block = adapter.getBlock(loc);
|
||||
System.out.println("Get tile " + x + "," + y + "," + z + " | " + (block != null ? block.getNbtData() : null) + " | done");
|
||||
return block != null ? block.getNbtData() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int x, int z) {
|
||||
return new BukkitChunk_All(this, x, z);
|
||||
|
@ -6,8 +6,9 @@ import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.IntegerTrio;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import java.util.HashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.Location;
|
||||
@ -46,11 +47,37 @@ public class ChunkListener implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Map<Long, Object> map = new Long2ObjectOpenHashMap<Object>() {
|
||||
@Override
|
||||
public Object put(long l, Object o) {
|
||||
synchronized (this) {
|
||||
return super.put(l, o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Object put(Long aLong, Object o) {
|
||||
return super.put(aLong, o);
|
||||
}
|
||||
};
|
||||
// map = new ConcurrentHashMap<>();
|
||||
long start = System.currentTimeMillis();
|
||||
for (int j = 0; j < 50000; j++) {
|
||||
for (long i = 0; i < 256; i++) {
|
||||
map.put(i, i);
|
||||
}
|
||||
map.clear();
|
||||
}
|
||||
System.out.println(System.currentTimeMillis() - start);
|
||||
System.out.println(map.size());
|
||||
}
|
||||
|
||||
public static boolean physicsFreeze = false;
|
||||
public static boolean itemFreeze = false;
|
||||
|
||||
private HashSet<Long> badChunks = new HashSet<>();
|
||||
private HashMap<Long, IntegerTrio> counter = new HashMap<>();
|
||||
private Map<Long, IntegerTrio> counter = new Long2ObjectOpenHashMap<>();
|
||||
private int lastX = Integer.MIN_VALUE, lastZ = Integer.MIN_VALUE;
|
||||
private IntegerTrio lastCount;
|
||||
|
||||
|
@ -396,19 +396,11 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
public class BukkitQueue_1_10 extends BukkitQueue_0<net.minecraft.server.v1_10_R1.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
@ -304,13 +304,42 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
CraftChunk chunk = (CraftChunk) world.getChunkAt(cx, cz);
|
||||
return chunk.getHandle().getSections();
|
||||
public int getBiome(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection[] getSections(net.minecraft.server.v1_10_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk;
|
||||
net.minecraft.server.v1_10_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_10_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_10_R1.ChunkSection getCachedSection(net.minecraft.server.v1_10_R1.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@ -350,27 +379,21 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return;
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_10 fs = (BukkitChunk_1_10) fc;
|
||||
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||
return;
|
||||
net.minecraft.server.v1_10_R1.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
Chunk chunk = fs.getChunk();
|
||||
sendChunk(chunk, fs.getBitMask());
|
||||
}
|
||||
|
||||
public void sendChunk(Chunk chunk, int mask) {
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
public void sendChunk(net.minecraft.server.v1_10_R1.Chunk nmsChunk, int mask) {
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
PlayerChunk playerChunk = chunkMap.getChunk(nmsChunk.locX, nmsChunk.locZ);
|
||||
@ -609,8 +632,8 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
protected BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_10_R1.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
@ -627,11 +650,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
|
@ -16,7 +16,9 @@ import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.internal.Constants;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -64,6 +66,40 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
public void storeBiomes(byte[] biomes) {
|
||||
this.biomes = Arrays.copyOf(biomes, biomes.length);
|
||||
}
|
||||
|
||||
public boolean storeTile(TileEntity tile, BlockPosition pos) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
CompoundTag nativeTag = getParent().getTag(tile);
|
||||
setTile(pos.getX() & 15, pos.getY(), pos.getZ() & 15, nativeTag);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean storeEntity(Entity ent) throws InvocationTargetException, IllegalAccessException {
|
||||
if (ent instanceof EntityPlayer) {
|
||||
return false;
|
||||
}
|
||||
int x = ((int) Math.round(ent.locX) & 15);
|
||||
int z = ((int) Math.round(ent.locZ) & 15);
|
||||
int y = ((int) Math.round(ent.locY) & 0xFF);
|
||||
int i = FaweCache.CACHE_I[y][z][x];
|
||||
int j = FaweCache.CACHE_J[y][z][x];
|
||||
String id = EntityTypes.b(ent);
|
||||
if (id != null) {
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
ent.e(tag); // readEntityIntoTag
|
||||
CompoundTag nativeTag = (CompoundTag) getParent().methodToNative.invoke(getParent().adapter, tag);
|
||||
Map<String, Tag> map = ReflectionUtils.getMap(nativeTag.getValue());
|
||||
map.put("Id", new StringTag(id));
|
||||
setEntity(nativeTag);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_11 copy;
|
||||
@ -174,6 +210,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
try {
|
||||
BukkitChunk_1_11_Copy copy = getParent().getChangeTask() != null ? new BukkitChunk_1_11_Copy(getParent(), getX(), getZ()) : null;
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
@ -186,8 +223,6 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// copy
|
||||
// BukkitChunk_1_11 copy = getParent().getFaweChunk(getX(), getZ()); // TODO
|
||||
// Set heightmap
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
// Remove entities
|
||||
@ -198,6 +233,9 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
Collection<Entity> ents = new ArrayList<>(entities[i]);
|
||||
for (Entity entity : ents) {
|
||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -211,7 +249,11 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
} else if (count >= 4096) {
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
// copy.storeEntities(this, i);
|
||||
if (copy != null) {
|
||||
for (Entity entity : ents) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
}
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
ents.clear();
|
||||
}
|
||||
@ -220,8 +262,7 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
Collection<Entity> ents = entities[i];
|
||||
if (!ents.isEmpty()) {
|
||||
char[] array = this.getIdArray(i);
|
||||
if (array == null || entities[i] == null || entities[i].isEmpty()) continue;
|
||||
ents = new ArrayList<>(entities[i]);
|
||||
if (array == null || ents == null || ents.isEmpty()) continue;
|
||||
synchronized (BukkitQueue_0.adapter) {
|
||||
for (Entity entity : ents) {
|
||||
if (entity instanceof EntityPlayer) {
|
||||
@ -232,7 +273,9 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
int y = (int) Math.round(entity.locY);
|
||||
if (y < 0 || y > 255) continue;
|
||||
if (array[FaweCache.CACHE_J[y][z][x]] != 0) {
|
||||
// copy.storeEntity(this, entity);
|
||||
if (copy != null) {
|
||||
copy.storeEntity(entity);
|
||||
}
|
||||
nmsWorld.removeEntity(entity);
|
||||
}
|
||||
}
|
||||
@ -291,11 +334,6 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
}
|
||||
}
|
||||
// Change task
|
||||
if (getParent().getChangeTask() != null) {
|
||||
BukkitChunk_1_11 previous = getParent().getPrevious(this, sections, tiles, entities, createdEntities, false);
|
||||
getParent().getChangeTask().run(previous, this);
|
||||
}
|
||||
// Trim tiles
|
||||
Iterator<Map.Entry<BlockPosition, TileEntity>> iterator = tiles.entrySet().iterator();
|
||||
HashMap<BlockPosition, TileEntity> toRemove = null;
|
||||
@ -315,11 +353,13 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
if (toRemove == null) {
|
||||
toRemove = new HashMap<>();
|
||||
}
|
||||
if (copy != null) {
|
||||
storeTile(tile.getValue(), tile.getKey());
|
||||
}
|
||||
toRemove.put(tile.getKey(), tile.getValue());
|
||||
}
|
||||
}
|
||||
if (toRemove != null) {
|
||||
// copy.storeTiles(this, toRemove);
|
||||
for (Map.Entry<BlockPosition, TileEntity> entry : toRemove.entrySet()) {
|
||||
BlockPosition bp = entry.getKey();
|
||||
TileEntity tile = entry.getValue();
|
||||
@ -342,7 +382,9 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
continue;
|
||||
}
|
||||
ChunkSection section = sections[j];
|
||||
// copy.storeBlocks(this, section);
|
||||
if (copy != null) {
|
||||
copy.storeSection(section, j);
|
||||
}
|
||||
if (section == null) {
|
||||
if (count == countAir) {
|
||||
continue;
|
||||
@ -410,20 +452,14 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
// copy.storeBiomes(this);
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
if (this.biomes != null) {
|
||||
if (copy != null) {
|
||||
copy.storeBiomes(nmsChunk.getBiomeIndex());
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -442,10 +478,10 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
tileEntity.a(tag); // ReadTagIntoTile
|
||||
}
|
||||
}
|
||||
// Change task?
|
||||
// if (getParent().getChangeTask() != null) { // TODO
|
||||
// getParent().getChangeTask().run(copy, this);
|
||||
// }
|
||||
// Change task
|
||||
if (copy != null) {
|
||||
getParent().getChangeTask().run(copy, this);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package com.boydti.fawe.bukkit.v1_11;
|
||||
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import net.minecraft.server.v1_11_R1.ChunkSection;
|
||||
import net.minecraft.server.v1_11_R1.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_11_R1.NibbleArray;
|
||||
|
||||
public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
|
||||
public final byte[][] idsBytes;
|
||||
@ -17,6 +20,21 @@ public class BukkitChunk_1_11_Copy extends BukkitChunk_1_11 {
|
||||
this.datasBytes[i] = data;
|
||||
}
|
||||
|
||||
public boolean storeSection(ChunkSection section, int layer) throws IllegalAccessException {
|
||||
if (section == null) {
|
||||
return false;
|
||||
}
|
||||
DataPaletteBlock blocks = section.getBlocks();
|
||||
byte[] ids = new byte[4096];
|
||||
NibbleArray data = new NibbleArray();
|
||||
blocks.exportData(ids, data);
|
||||
set(layer, ids, data.asBytes());
|
||||
short solid = (short) getParent().fieldNonEmptyBlockCount.getInt(section);
|
||||
count[layer] = solid;
|
||||
air[layer] = (short) (4096 - solid);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public char[][] getCombinedIdArrays() {
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
|
@ -68,7 +68,7 @@ import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
public class BukkitQueue_1_11 extends BukkitQueue_0<net.minecraft.server.v1_11_R1.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
@ -150,6 +150,41 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getSections(net.minecraft.server.v1_11_R1.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_11_R1.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk;
|
||||
net.minecraft.server.v1_11_R1.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_11_R1.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_11_R1.CraftWorld) world).getHandle().getChunkProviderServer().getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(World world, int x, int z, BaseBiome biome, Long seed) {
|
||||
if (biome != null) {
|
||||
@ -310,17 +345,6 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
CraftChunk chunk = (CraftChunk) world.getChunkAt(cx, cz);
|
||||
return chunk.getHandle().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection lastSection, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = lastSection.getBlocks();
|
||||
@ -334,6 +358,11 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(net.minecraft.server.v1_11_R1.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(ChunkSection section, int x, int y, int z) {
|
||||
DataPaletteBlock dataPalette = section.getBlocks();
|
||||
@ -357,27 +386,21 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return;
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_11 fs = (BukkitChunk_1_11) fc;
|
||||
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||
return;
|
||||
net.minecraft.server.v1_11_R1.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
Chunk chunk = fs.getChunk();
|
||||
sendChunk(chunk, fs.getBitMask());
|
||||
}
|
||||
|
||||
public void sendChunk(Chunk chunk, int mask) {
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
net.minecraft.server.v1_11_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
public void sendChunk(net.minecraft.server.v1_11_R1.Chunk nmsChunk, int mask) {
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
PlayerChunk playerChunk = chunkMap.getChunk(nmsChunk.locX, nmsChunk.locZ);
|
||||
@ -387,6 +410,13 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
if (playerChunk.c.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (mask == 0) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65535);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Send chunks
|
||||
boolean empty = false;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
@ -396,7 +426,7 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
empty = true;
|
||||
}
|
||||
}
|
||||
if (mask == 0 || mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
if (mask == 0 || mask == 65535 && hasEntities(nmsChunk)) {
|
||||
PacketPlayOutMapChunk packet = new PacketPlayOutMapChunk(nmsChunk, 65280);
|
||||
for (EntityPlayer player : playerChunk.c) {
|
||||
player.playerConnection.sendPacket(packet);
|
||||
@ -600,8 +630,8 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
protected BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_11_R1.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
@ -618,11 +648,6 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_11_R1.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
|
@ -352,19 +352,11 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
}
|
||||
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.m()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome; // Biome array
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.m();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,7 +48,6 @@ import net.minecraft.server.v1_7_R4.WorldServer;
|
||||
import net.minecraft.server.v1_7_R4.WorldSettings;
|
||||
import net.minecraft.server.v1_7_R4.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
@ -59,7 +58,7 @@ import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
public class BukkitQueue17 extends BukkitQueue_0<net.minecraft.server.v1_7_R4.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static Field fieldData;
|
||||
protected static Field fieldIds;
|
||||
@ -175,18 +174,48 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return getWorld().isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
public World getWorld(String world) {
|
||||
return Bukkit.getWorld(world);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(World world, int x, int z, boolean generate) {
|
||||
return getCachedSections(world, x, z) != null;
|
||||
public int getBiome(net.minecraft.server.v1_7_R4.Chunk chunk, int x, int z) {
|
||||
return chunk.m()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection[] getSections(net.minecraft.server.v1_7_R4.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk;
|
||||
net.minecraft.server.v1_7_R4.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer;
|
||||
if (generate) {
|
||||
return provider.getOrCreateChunk(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_7_R4.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_7_R4.ChunkSection getCachedSection(net.minecraft.server.v1_7_R4.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -200,18 +229,6 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int x, int z) {
|
||||
Chunk chunk = world.getChunkAt(x, z);
|
||||
if (chunk == null) {
|
||||
return null;
|
||||
}
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load(true);
|
||||
}
|
||||
return ((CraftChunk) chunk).getHandle().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection ls, int x, int y, int z) {
|
||||
byte[] ids = ls.getIdArray();
|
||||
@ -221,16 +238,6 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
return combined;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(World world, int x, int z) {
|
||||
return world.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<ChunkPosition, TileEntity> tiles = (Map<ChunkPosition, TileEntity>) tilesGeneric;
|
||||
@ -307,19 +314,14 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<ChunkPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().tileEntities;
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_7_R4.Chunk chunk, int x, int y, int z) {
|
||||
Map<ChunkPosition, TileEntity> tiles = chunk.tileEntities;
|
||||
ChunkPosition pos = new ChunkPosition(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
@ -331,28 +333,22 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return;
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_7 fs = (BukkitChunk_1_7) fc;
|
||||
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||
return;
|
||||
net.minecraft.server.v1_7_R4.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
Chunk chunk = fs.getChunk();
|
||||
sendChunk(chunk, fs.getBitMask());
|
||||
}
|
||||
|
||||
public void sendChunk(Chunk chunk, int mask) {
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
public void sendChunk(net.minecraft.server.v1_7_R4.Chunk nmsChunk, int mask) {
|
||||
try {
|
||||
net.minecraft.server.v1_7_R4.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
ChunkCoordIntPair pos = nmsChunk.l(); // getPosition()
|
||||
WorldServer w = (WorldServer) nmsChunk.world;
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
|
@ -285,19 +285,11 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
}
|
||||
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
if (this.biomes != null) {
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0 ; i < this.biomes.length; i++) {
|
||||
if (this.biomes[i] != 0) {
|
||||
currentBiomes[i] = this.biomes[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,6 @@ import net.minecraft.server.v1_8_R3.WorldServer;
|
||||
import net.minecraft.server.v1_8_R3.WorldSettings;
|
||||
import net.minecraft.server.v1_8_R3.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldCreator;
|
||||
import org.bukkit.block.Biome;
|
||||
@ -58,7 +57,7 @@ import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
public class BukkitQueue18R3 extends BukkitQueue_0<net.minecraft.server.v1_8_R3.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
public static Field isDirty;
|
||||
|
||||
@ -180,17 +179,43 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return getWorld().isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
public World getWorld(String world) {
|
||||
return Bukkit.getWorld(world);
|
||||
public int getBiome(net.minecraft.server.v1_8_R3.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(World world, int x, int z, boolean generate) {
|
||||
return getCachedSections(world, x, z) != null;
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection[] getSections(net.minecraft.server.v1_8_R3.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk;
|
||||
net.minecraft.server.v1_8_R3.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_8_R3.CraftWorld) world).getHandle().chunkProviderServer;
|
||||
if (generate) {
|
||||
return provider.getOrCreateChunk(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = ((CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_8_R3.CraftWorld) world).getHandle().chunkProviderServer.getChunkIfLoaded(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_8_R3.ChunkSection getCachedSection(net.minecraft.server.v1_8_R3.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -204,34 +229,12 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int x, int z) {
|
||||
Chunk chunk = world.getChunkAt(x, z);
|
||||
if (chunk == null) {
|
||||
return null;
|
||||
}
|
||||
if (!chunk.isLoaded()) {
|
||||
chunk.load(true);
|
||||
}
|
||||
return ((CraftChunk) chunk).getHandle().getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4Data(ChunkSection section, int x, int y, int z) {
|
||||
char[] ls = section.getIdArray();
|
||||
return ls[FaweCache.CACHE_J[y][z & 15][x & 15]];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(World world, int x, int z) {
|
||||
return world.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk getPrevious(CharFaweChunk fs, ChunkSection[] sections, Map<?, ?> tilesGeneric, Collection<?>[] entitiesGeneric, Set<UUID> createdEntities, boolean all) throws Exception {
|
||||
Map<BlockPosition, TileEntity> tiles = (Map<BlockPosition, TileEntity>) tilesGeneric;
|
||||
@ -309,19 +312,14 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
private BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_8_R3.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
@ -333,28 +331,22 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return;
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_8 fs = (BukkitChunk_1_8) fc;
|
||||
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||
return;
|
||||
net.minecraft.server.v1_8_R3.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
Chunk chunk = fs.getChunk();
|
||||
sendChunk(chunk, fs.getBitMask());
|
||||
}
|
||||
|
||||
public void sendChunk(Chunk chunk, int mask) {
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
public void sendChunk(net.minecraft.server.v1_8_R3.Chunk nmsChunk, int mask) {
|
||||
try {
|
||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
int x = nmsChunk.locX;
|
||||
|
@ -39,7 +39,6 @@ import net.minecraft.server.v1_9_R2.NBTTagCompound;
|
||||
import net.minecraft.server.v1_9_R2.TileEntity;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.craftbukkit.v1_9_R2.CraftChunk;
|
||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||
|
||||
@ -403,19 +402,13 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
byte[] biomes = this.biomes;
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
nmsChunk.getBiomeIndex()[((z & 0xF) << 4 | x & 0xF)] = (byte) biome;
|
||||
byte[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||
for (int i = 0; i < currentBiomes.length; i++) {
|
||||
byte newBiome = biomes[i];
|
||||
if (newBiome != 0) {
|
||||
currentBiomes[i] = newBiome;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -437,23 +430,6 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
} catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
final int[][] biomes = this.getBiomeArray();
|
||||
final Biome[] values = Biome.values();
|
||||
if (biomes != null) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
final int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
for (int z = 0; z < 16; z++) {
|
||||
final int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
chunk.getBlock(x, 0, z).setBiome(values[biome]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
@ -62,7 +62,7 @@ import org.bukkit.event.world.WorldInitEvent;
|
||||
import org.bukkit.event.world.WorldLoadEvent;
|
||||
import org.bukkit.generator.ChunkGenerator;
|
||||
|
||||
public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
|
||||
public class BukkitQueue_1_9_R1 extends BukkitQueue_0<net.minecraft.server.v1_9_R2.Chunk, ChunkSection[], ChunkSection> {
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
@ -191,13 +191,42 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
CraftChunk chunk = (CraftChunk) world.getChunkAt(cx, cz);
|
||||
return chunk.getHandle().getSections();
|
||||
public int getBiome(net.minecraft.server.v1_9_R2.Chunk chunk, int x, int z) {
|
||||
return chunk.getBiomeIndex()[((z & 15) << 4) + (x & 15)];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection[] getSections(net.minecraft.server.v1_9_R2.Chunk chunk) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.Chunk loadChunk(World world, int x, int z, boolean generate) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk;
|
||||
net.minecraft.server.v1_9_R2.ChunkProviderServer provider = ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer();
|
||||
if (generate) {
|
||||
return provider.getOrLoadChunkAt(x, z);
|
||||
} else {
|
||||
return provider.loadChunk(x, z);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection[] getCachedSections(World world, int cx, int cz) {
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer().getLoadedChunkAt(cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk.getSections();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.Chunk getCachedChunk(World world, int cx, int cz) {
|
||||
return ((org.bukkit.craftbukkit.v1_9_R2.CraftWorld) world).getHandle().getChunkProviderServer().getLoadedChunkAt(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public net.minecraft.server.v1_9_R2.ChunkSection getCachedSection(net.minecraft.server.v1_9_R2.ChunkSection[] chunkSections, int cy) {
|
||||
return chunkSections[cy];
|
||||
}
|
||||
|
||||
@ -216,27 +245,21 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
|
||||
@Override
|
||||
public void sendChunk(int x, int z, int bitMask) {
|
||||
if (!isChunkLoaded(x, z)) {
|
||||
return;
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = getCachedChunk(getWorld(), x, z);
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, bitMask);
|
||||
}
|
||||
sendChunk(getWorld().getChunkAt(x, z), bitMask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_9 fs = (BukkitChunk_1_9) fc;
|
||||
if (!isChunkLoaded(fc.getX(), fc.getZ())) {
|
||||
return;
|
||||
net.minecraft.server.v1_9_R2.Chunk chunk = getCachedChunk(getWorld(), fc.getX(), fc.getZ());
|
||||
if (chunk != null) {
|
||||
sendChunk(chunk, fc.getBitMask());
|
||||
}
|
||||
Chunk chunk = fs.getChunk();
|
||||
sendChunk(chunk, fs.getBitMask());
|
||||
}
|
||||
|
||||
public void sendChunk(Chunk chunk, int mask) {
|
||||
if (!chunk.isLoaded()) {
|
||||
return;
|
||||
}
|
||||
net.minecraft.server.v1_9_R2.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
public void sendChunk(net.minecraft.server.v1_9_R2.Chunk nmsChunk, int mask) {
|
||||
WorldServer w = (WorldServer) nmsChunk.getWorld();
|
||||
PlayerChunkMap chunkMap = w.getPlayerChunkMap();
|
||||
PlayerChunk playerChunk = chunkMap.getChunk(nmsChunk.locX, nmsChunk.locZ);
|
||||
@ -560,8 +583,8 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
protected BlockPosition.MutableBlockPosition pos = new BlockPosition.MutableBlockPosition(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = ((CraftChunk) chunk).getHandle().getTileEntities();
|
||||
public CompoundTag getTileEntity(net.minecraft.server.v1_9_R2.Chunk chunk, int x, int y, int z) {
|
||||
Map<BlockPosition, TileEntity> tiles = chunk.getTileEntities();
|
||||
pos.c(x, y, z);
|
||||
TileEntity tile = tiles.get(pos);
|
||||
return tile != null ? getTag(tile) : null;
|
||||
@ -578,11 +601,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Chunk getChunk(World world, int x, int z) {
|
||||
return world.getChunkAt(x, z);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public boolean unloadChunk(final String world, final Chunk chunk) {
|
||||
net.minecraft.server.v1_9_R2.Chunk c = ((CraftChunk) chunk).getHandle();
|
||||
|
@ -805,7 +805,7 @@ public class AsyncWorld extends DelegateFaweQueue implements World, HasFaweQueue
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
throw new UnsupportedOperationException("NOT IMPLEMENTED");
|
||||
return adapter.getBiome(queue.getBiomeId(x, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -7,6 +7,7 @@ dependencies {
|
||||
compile 'com.plotsquared:PlotSquared:3.4.1-SNAPSHOT'
|
||||
compile 'org.primesoft:BlocksHub:2.0'
|
||||
compile 'com.github.luben:zstd-jni:1.1.1'
|
||||
compile 'co.aikar:fastutil-lite:1.0'
|
||||
compile(group: 'com.sk89q.worldedit', name: 'worldedit-core', version:'6.1.3-SNAPSHOT') {
|
||||
exclude(module: 'bukkit-classloader-check')
|
||||
}
|
||||
|
@ -16,7 +16,6 @@ import com.boydti.fawe.util.StringMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.boydti.fawe.util.Updater;
|
||||
import com.boydti.fawe.util.WEManager;
|
||||
import com.boydti.fawe.util.WESubscriber;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
@ -25,6 +24,7 @@ import com.sk89q.worldedit.CuboidClipboard;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.blocks.BlockData;
|
||||
import com.sk89q.worldedit.command.BiomeCommands;
|
||||
@ -254,7 +254,6 @@ public class Fawe {
|
||||
Fawe.debug("Plugin 'PlotSquared' found. Using it now.");
|
||||
} catch (Throwable e) {}
|
||||
Fawe.this.worldedit = WorldEdit.getInstance();
|
||||
Fawe.this.setupEvents();
|
||||
}
|
||||
}, 0);
|
||||
|
||||
@ -298,10 +297,6 @@ public class Fawe {
|
||||
return timer.getTPS();
|
||||
}
|
||||
|
||||
private void setupEvents() {
|
||||
WorldEdit.getInstance().getEventBus().register(new WESubscriber());
|
||||
}
|
||||
|
||||
private void setupCommands() {
|
||||
this.IMP.setupCommand("wea", new Wea());
|
||||
this.IMP.setupCommand("select", new WorldEditRegion());
|
||||
@ -417,6 +412,7 @@ public class Fawe {
|
||||
BlockWorldVector.inject(); // Optimizations
|
||||
BlockVector.inject(); // Optimizations
|
||||
Vector.inject(); // Optimizations
|
||||
Vector2D.inject(); // Optimizations
|
||||
// Pattern
|
||||
Patterns.inject(); // Optimizations (reduce object creation)
|
||||
RandomPattern.inject(); // Optimizations
|
||||
@ -538,6 +534,11 @@ public class Fawe {
|
||||
ne.addNotificationListener(new NotificationListener() {
|
||||
@Override
|
||||
public void handleNotification(final Notification notification, final Object handback) {
|
||||
final long heapSize = Runtime.getRuntime().totalMemory();
|
||||
final long heapMaxSize = Runtime.getRuntime().maxMemory();
|
||||
if (heapSize < heapMaxSize) {
|
||||
return;
|
||||
}
|
||||
MemUtil.memoryLimitedTask();
|
||||
}
|
||||
}, null, null);
|
||||
|
@ -17,6 +17,7 @@ import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.CuboidClipboard;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.blocks.BaseItem;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||
import java.awt.Color;
|
||||
import java.lang.reflect.Field;
|
||||
@ -60,6 +61,11 @@ public class FaweCache {
|
||||
*/
|
||||
public final static byte[] CACHE_DATA = new byte[65535];
|
||||
|
||||
/**
|
||||
* Immutable biome cache
|
||||
*/
|
||||
public final static BaseBiome[] CACHE_BIOME = new BaseBiome[256];
|
||||
|
||||
/**
|
||||
* Immutable BaseBlock cache
|
||||
* [ combined ] => block
|
||||
@ -129,7 +135,19 @@ public class FaweCache {
|
||||
return CACHE_COLOR[0];
|
||||
}
|
||||
|
||||
public static final BaseBiome getBiome(int id) {
|
||||
return CACHE_BIOME[id];
|
||||
}
|
||||
|
||||
static {
|
||||
for (int i = 0; i < 256; i++) {
|
||||
CACHE_BIOME[i] = new BaseBiome(i) {
|
||||
@Override
|
||||
public void setId(int id) {
|
||||
throw new IllegalStateException("Cannot set id");
|
||||
}
|
||||
};
|
||||
}
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int y = 0; y < 256; y++) {
|
||||
|
@ -76,9 +76,11 @@ public enum BBC {
|
||||
COMMAND_REGEN_1("Region regenerated.\nTip: Use a seed with /regen [biome] [seed]", "WorldEdit.Regen"),
|
||||
COMMAND_REGEN_2("Region regenerated.", "WorldEdit.Regen"),
|
||||
COMMAND_TREE("%s0 trees created.", "WorldEdit.Tree"),
|
||||
COMMAND_PUMPKIN("%s0 pumpkin patches created.", "WorldEdit.Tree"),
|
||||
COMMAND_FLORA("%s0 flora created.", "WorldEdit.Flora"),
|
||||
COMMAND_HISTORY_CLEAR("History cleared", "WorldEdit.History"),
|
||||
COMMAND_REDO_ERROR("Nothing left to redo. (See also `/inspect` and `/frb`)", "WorldEdit.History"),
|
||||
COMMAND_HISTORY_OTHER_ERROR("Unable to find session for %s0.", "WorldEdit.History"),
|
||||
COMMAND_REDO_SUCCESS("Redo successful.", "WorldEdit.History"),
|
||||
COMMAND_UNDO_ERROR("Nothing left to undo. (See also `/inspect` and `/frb`)", "WorldEdit.History"),
|
||||
COMMAND_UNDO_SUCCESS("Undo successful.", "WorldEdit.History"),
|
||||
@ -133,6 +135,7 @@ public enum BBC {
|
||||
BRUSH_TRANSFORM("Brush transform set", "WorldEdit.Brush"),
|
||||
BRUSH_MATERIAL("Brush material set", "WorldEdit.Brush"),
|
||||
|
||||
|
||||
ROLLBACK_ELEMENT("Undoing %s0", "WorldEdit.Rollback"),
|
||||
|
||||
TOOL_INSPECT("Inspect tool bound to %s0.", "WorldEdit.Tool"),
|
||||
@ -145,13 +148,32 @@ public enum BBC {
|
||||
TOOL_REPL("Block replacer tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_CYCLER("Block data cycler tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_FLOOD_FILL("Block flood fill tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_FLOOD_FILL_RANGE_ERROR("Maximum range: %s0.", "WorldEdit.Tool"),
|
||||
TOOL_RANGE_ERROR("Maximum range: %s0.", "WorldEdit.Tool"),
|
||||
TOOL_RADIUS_ERROR("Maximum allowed brush radius: %s0.", "WorldEdit.Tool"),
|
||||
TOOL_DELTREE("Floating tree remover tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_FARWAND("Far wand tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_LRBUILD_BOUND("Long-range building tool bound to %s0.", "WorldEdit.Tool"),
|
||||
TOOL_LRBUILD_INFO("Left-click set to %s0; right-click set to %s1.", "WorldEdit.Tool"),
|
||||
SUPERPICKAXE_ENABLED("Super Pickaxe enabled.", "WorldEdit.Tool"),
|
||||
SUPERPICKAXE_DISABLED("Super Pickaxe disabled.", "WorldEdit.Tool"),
|
||||
SUPERPICKAXE_AREA_ENABLED("Mode changed. Left click with a pickaxe. // to disable.", "WorldEdit.Tool"),
|
||||
|
||||
SNAPSHOT_LOADED("Snapshot '%s0' loaded; now restoring...", "WorldEdit.Snapshot"),
|
||||
SNAPSHOT_SET("Snapshot set to: %s0", "WorldEdit.Snapshot"),
|
||||
SNAPSHOT_NEWEST("Now using newest snapshot.", "WorldEdit.Snapshot"),
|
||||
SNAPSHOT_LIST_HEADER("Snapshots for world (%s0):", "WorldEdit.Snapshot"),
|
||||
SNAPSHOT_LIST_FOOTER("Use /snap use [snapshot] or /snap use latest.", "WorldEdit.Snapshot"),
|
||||
|
||||
BIOME_LIST_HEADER("Biomes (page %s0/%s1):", "WorldEdit.Biome"),
|
||||
BIOME_CHANGED("Biomes were changed in %s0 columns.", "WorldEdit.Biome"),
|
||||
|
||||
FAST_ENABLED("Fast mode enabled. History and edit restrictions will be bypassed.", "WorldEdit.General"),
|
||||
FAST_DISABLED("Fast mode disabled", "WorldEdit.General"),
|
||||
|
||||
PLACE_ENABLED("Now placing at pos #1.", "WorldEdit.General"),
|
||||
PLACE_DISABLED("Now placing at the block you stand in.", "WorldEdit.General"),
|
||||
|
||||
KILL_SUCCESS("Killed %s0 entities in a radius of %s1.", "WorldEdit.Utility"),
|
||||
|
||||
|
||||
SCHEMATIC_DELETE("%s0 has been deleted.", "Worldedit.Schematic"),
|
||||
@ -163,6 +185,7 @@ public enum BBC {
|
||||
SCHEMATIC_LIST("Available schematics (Filename: Format) [%s0/%s1]:", "Worldedit.Schematic"),
|
||||
|
||||
CLIPBOARD_CLEARED("Clipboard cleared", "WorldEdit.Clipboard"),
|
||||
CLIPBOARD_INVALID_FORMAT("Unknown clipboard format: %s0", "WorldEdit.Clipboard"),
|
||||
|
||||
VISITOR_BLOCK("%s0 blocks affected", "WorldEdit.Visitor"),
|
||||
VISITOR_ENTITY("%s0 entities affected", "WorldEdit.Visitor"),
|
||||
@ -174,6 +197,10 @@ public enum BBC {
|
||||
SELECTOR_CUBOID_POS2("pos2 set to %s0 %s1.", "WorldEdit.Selector"),
|
||||
SELECTOR_INVALID_COORDINATES("Invalid coordinates %s0", "WorldEdit.Selector"),
|
||||
SELECTOR_ALREADY_SET("Position already set.", "WorldEdit.Selector"),
|
||||
SELECTOR_SET_DEFAULT("Your default region selector is now %s0.", "WorldEdit.Selector"),
|
||||
|
||||
TIMEZONE_SET("Timezone set for this session to: %s0", "WorldEdit.Timezone"),
|
||||
TIMEZONE_DISPLAY("The current time in that timezone is: %s0", "WorldEdit.Timezone"),
|
||||
|
||||
COMMAND_INVALID_SYNTAX("The command was not used properly (no more help available).", "WorldEdit.Command"),
|
||||
|
||||
@ -222,7 +249,7 @@ public enum BBC {
|
||||
WHOOSH("Whoosh!", "Navigation"),
|
||||
POOF("Poof!", "Navigation"),
|
||||
THRU_FAIL("No free spot ahead of you found.", "Navigation"),
|
||||
JUMPTO_FAIL("No block in sight!", "Navigation"),
|
||||
NO_BLOCK("No block in sight! (or too far)", "Navigation"),
|
||||
UP_FAIL("You would hit something above you.", "Navigation"),
|
||||
|
||||
SEL_CUBOID("Cuboid: left click for point 1, right click for point 2", "Selection"),
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.configuration.MemorySection;
|
||||
import com.boydti.fawe.configuration.file.YamlConfiguration;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.ElementType;
|
||||
@ -22,6 +23,10 @@ import java.util.Map;
|
||||
|
||||
public class Config {
|
||||
|
||||
public Config() {
|
||||
save(new PrintWriter(new ByteArrayOutputStream(0)), getClass(), this, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the value for a node<br>
|
||||
* Probably throws some error if you try to get a non existent key
|
||||
@ -220,7 +225,7 @@ public class Config {
|
||||
return value != null ? value.toString() : "null";
|
||||
}
|
||||
|
||||
private void save(PrintWriter writer, Class clazz, Object instance, int indent) {
|
||||
private void save(PrintWriter writer, Class clazz, final Object instance, int indent) {
|
||||
try {
|
||||
String CTRF = System.lineSeparator();
|
||||
String spacing = StringMan.repeat(" ", indent);
|
||||
|
@ -18,13 +18,13 @@ public class Settings extends Config {
|
||||
@Final
|
||||
public final String WIKI = "https://github.com/boy0001/FastAsyncWorldedit/wiki/";
|
||||
@Final
|
||||
public String DATE = null; // These values are set from FAWE before loading
|
||||
public String DATE; // These values are set from FAWE before loading
|
||||
@Final
|
||||
public String BUILD = null; // These values are set from FAWE before loading
|
||||
public String BUILD; // These values are set from FAWE before loading
|
||||
@Final
|
||||
public String COMMIT = null; // These values are set from FAWE before loading
|
||||
public String COMMIT; // These values are set from FAWE before loading
|
||||
@Final
|
||||
public String PLATFORM = null; // These values are set from FAWE before loading
|
||||
public String PLATFORM; // These values are set from FAWE before loading
|
||||
|
||||
@Comment("Allow the plugin to update")
|
||||
public boolean UPDATE = true;
|
||||
@ -46,23 +46,23 @@ public class Settings extends Config {
|
||||
public int MAX_MEMORY_PERCENT = 95;
|
||||
|
||||
@Create
|
||||
public CLIPBOARD CLIPBOARD = null;
|
||||
public CLIPBOARD CLIPBOARD;
|
||||
@Create
|
||||
public LIGHTING LIGHTING = null;
|
||||
public LIGHTING LIGHTING;
|
||||
@Create
|
||||
public TICK_LIMITER TICK_LIMITER = null;
|
||||
public TICK_LIMITER TICK_LIMITER;
|
||||
@Create
|
||||
public WEB WEB = null;
|
||||
public WEB WEB;
|
||||
@Create
|
||||
public EXTENT EXTENT = null;
|
||||
public EXTENT EXTENT;
|
||||
@Create
|
||||
public EXPERIMENTAL EXPERIMENTAL = null;
|
||||
public EXPERIMENTAL EXPERIMENTAL;
|
||||
@Create
|
||||
public QUEUE QUEUE = null;
|
||||
public QUEUE QUEUE;
|
||||
@Create
|
||||
public HISTORY HISTORY = null;
|
||||
public HISTORY HISTORY;
|
||||
@Create
|
||||
public PATHS PATHS = null;
|
||||
public PATHS PATHS;
|
||||
|
||||
@Comment("Paths for various directories")
|
||||
public static final class PATHS {
|
||||
@ -72,7 +72,7 @@ public class Settings extends Config {
|
||||
|
||||
|
||||
@Create // This value will be generated automatically
|
||||
public ConfigBlock<LIMITS> LIMITS = null;
|
||||
public ConfigBlock<LIMITS> LIMITS;
|
||||
|
||||
@Comment({
|
||||
"The \"default\" limit group affects those without a specific limit permission.",
|
||||
@ -208,7 +208,7 @@ public class Settings extends Config {
|
||||
|
||||
public static class QUEUE {
|
||||
@Create
|
||||
public static PROGRESS PROGRESS = null;
|
||||
public static PROGRESS PROGRESS;
|
||||
@Comment({
|
||||
"If no blocks from completed edits are queued, and if the global queue has more available ",
|
||||
"chunks to place from still-processing edits than the target size setting, it will begin",
|
||||
|
@ -5,7 +5,6 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -19,7 +18,7 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
public final short[] air;
|
||||
public final byte[] heightMap;
|
||||
|
||||
public int[][] biomes;
|
||||
public byte[] biomes;
|
||||
public HashMap<Short, CompoundTag> tiles;
|
||||
public HashSet<CompoundTag> entities;
|
||||
public HashSet<UUID> entityRemoves;
|
||||
@ -121,7 +120,8 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
return this.ids;
|
||||
}
|
||||
|
||||
public int[][] getBiomeArray() {
|
||||
@Override
|
||||
public byte[] getBiomeArray() {
|
||||
return this.biomes;
|
||||
}
|
||||
|
||||
@ -342,15 +342,11 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(final int x, final int z, final BaseBiome biome) {
|
||||
public void setBiome(final int x, final int z, final byte biome) {
|
||||
if (this.biomes == null) {
|
||||
this.biomes = new int[16][];
|
||||
this.biomes = new byte[256];
|
||||
}
|
||||
int[] index = this.biomes[x];
|
||||
if (index == null) {
|
||||
index = this.biomes[x] = new int[16];
|
||||
}
|
||||
index[z] = biome.getId();
|
||||
biomes[((z & 15) << 4) + (x & 15)] = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -5,11 +5,11 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
|
||||
public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
@ -20,12 +20,14 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of chunks in the queue
|
||||
*/
|
||||
public final ConcurrentHashMap<Long, FaweChunk> blocks = new ConcurrentHashMap<Long, FaweChunk>(8, 0.9f, 1) {
|
||||
public final Long2ObjectOpenHashMap<FaweChunk> blocks = new Long2ObjectOpenHashMap<FaweChunk>() {
|
||||
@Override
|
||||
public FaweChunk put(Long key, FaweChunk value) {
|
||||
return put((long) key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk put(long key, FaweChunk value) {
|
||||
if (parent.getProgressTask() != null) {
|
||||
try {
|
||||
parent.getProgressTask().run(FaweQueue.ProgressType.QUEUE, size() + 1);
|
||||
@ -33,8 +35,10 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@ -109,6 +113,7 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, ExecutorCompletionService pool, long time) {
|
||||
synchronized (blocks) {
|
||||
try {
|
||||
boolean skip = parent.getStage() == SetQueue.QueueStage.INACTIVE;
|
||||
int added = 0;
|
||||
@ -173,3 +178,4 @@ public class DefaultFaweQueueMap implements IFaweQueueMap {
|
||||
return !blocks.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,17 +21,36 @@ import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
public abstract class MappedFaweQueue<WORLD, CHUNK, CHUNKSECTIONS, SECTION> extends FaweQueue {
|
||||
|
||||
private WORLD impWorld;
|
||||
|
||||
private IFaweQueueMap map;
|
||||
|
||||
public int lastSectionX = Integer.MIN_VALUE;
|
||||
public int lastSectionZ = Integer.MIN_VALUE;
|
||||
public int lastSectionY = Integer.MIN_VALUE;
|
||||
public CHUNK lastChunk;
|
||||
public CHUNKSECTIONS lastChunkSections;
|
||||
public SECTION lastSection;
|
||||
|
||||
private CHUNK cachedLoadChunk;
|
||||
public final RunnableVal<IntegerPair> loadChunk = new RunnableVal<IntegerPair>() {
|
||||
|
||||
{
|
||||
this.value = new IntegerPair(0, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(IntegerPair coord) {
|
||||
cachedLoadChunk = loadChunk(getWorld(), coord.x, coord.z, true);
|
||||
}
|
||||
};
|
||||
|
||||
public MappedFaweQueue(final World world) {
|
||||
this(world, null);
|
||||
}
|
||||
@ -102,21 +121,18 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
|
||||
public abstract WORLD getImpWorld();
|
||||
|
||||
public abstract boolean isChunkLoaded(WORLD world, int x, int z);
|
||||
|
||||
public abstract boolean regenerateChunk(WORLD world, int x, int z, BaseBiome biome, Long seed);
|
||||
|
||||
@Override
|
||||
public abstract FaweChunk getFaweChunk(int x, int z);
|
||||
|
||||
public abstract boolean loadChunk(WORLD world, int x, int z, boolean generate);
|
||||
public abstract CHUNK loadChunk(WORLD world, int x, int z, boolean generate);
|
||||
|
||||
public abstract CHUNK getCachedSections(WORLD world, int cx, int cz);
|
||||
public abstract CHUNKSECTIONS getSections(CHUNK chunk);
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return isChunkLoaded(getWorld(), x, z);
|
||||
};
|
||||
public abstract CHUNKSECTIONS getCachedSections(WORLD world, int cx, int cz);
|
||||
|
||||
public abstract CHUNK getCachedChunk(WORLD world, int cx, int cz);
|
||||
|
||||
public WORLD getWorld() {
|
||||
if (impWorld != null) {
|
||||
@ -233,16 +249,12 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
@Override
|
||||
public int size() {
|
||||
int size = map.size();
|
||||
if (size == 0 && getStage() != SetQueue.QueueStage.INACTIVE) {
|
||||
if (size == 0 && getStage() == SetQueue.QueueStage.NONE) {
|
||||
runTasks();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
private ConcurrentLinkedDeque<FaweChunk> toUpdate = new ConcurrentLinkedDeque<>();
|
||||
|
||||
private int dispatched = 0;
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
map.clear();
|
||||
@ -254,66 +266,78 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
map.add(chunk);
|
||||
}
|
||||
|
||||
public int lastChunkX = Integer.MIN_VALUE;
|
||||
public int lastChunkZ = Integer.MIN_VALUE;
|
||||
public int lastChunkY = Integer.MIN_VALUE;
|
||||
|
||||
public CHUNK lastChunkSections;
|
||||
public SECTION lastSection;
|
||||
|
||||
public SECTION getCachedSection(CHUNK chunk, int cy) {
|
||||
public SECTION getCachedSection(CHUNKSECTIONS chunk, int cy) {
|
||||
return (SECTION) lastChunkSections;
|
||||
}
|
||||
|
||||
public abstract int getCombinedId4Data(SECTION section, int x, int y, int z);
|
||||
|
||||
public final RunnableVal<IntegerPair> loadChunk = new RunnableVal<IntegerPair>() {
|
||||
@Override
|
||||
public void run(IntegerPair coord) {
|
||||
loadChunk(getWorld(), coord.x, coord.z, true);
|
||||
public abstract int getBiome(CHUNK chunk, int x, int z);
|
||||
|
||||
public abstract CompoundTag getTileEntity(CHUNK chunk, int x, int y, int z);
|
||||
|
||||
// public CHUNKSECTIONS ensureSectionsLoaded(int cx, int cz) throws FaweException.FaweChunkLoadException {
|
||||
// CHUNKSECTIONS sections = getCachedSections(getWorld(), cx, cz);
|
||||
// if (sections != null) {
|
||||
// return sections;
|
||||
// }
|
||||
// boolean sync = Thread.currentThread() == Fawe.get().getMainThread();
|
||||
// if (sync) {
|
||||
// CHUNK chunk = loadChunk(getWorld(), cx, cz, true);
|
||||
// return chunk != null ? getSections(chunk) : null;
|
||||
// } else if (Settings.IMP.HISTORY.CHUNK_WAIT_MS > 0) {
|
||||
// cachedLoadChunk = null;
|
||||
// loadChunk.value.x = cx;
|
||||
// loadChunk.value.z = cz;
|
||||
// TaskManager.IMP.syncWhenFree(loadChunk, Settings.IMP.HISTORY.CHUNK_WAIT_MS);
|
||||
// return cachedLoadChunk != null ? getSections(cachedLoadChunk) : null;
|
||||
// } else {
|
||||
// return null;
|
||||
// }
|
||||
// }
|
||||
|
||||
public CHUNK ensureChunkLoaded(int cx, int cz) throws FaweException.FaweChunkLoadException {
|
||||
CHUNK chunk = getCachedChunk(getWorld(), cx, cz);
|
||||
if (chunk != null) {
|
||||
return chunk;
|
||||
}
|
||||
};
|
||||
|
||||
long average = 0;
|
||||
|
||||
public boolean ensureChunkLoaded(int cx, int cz) throws FaweException.FaweChunkLoadException {
|
||||
if (!isChunkLoaded(cx, cz)) {
|
||||
boolean sync = Thread.currentThread() == Fawe.get().getMainThread();
|
||||
if (sync) {
|
||||
loadChunk(getWorld(), cx, cz, true);
|
||||
return loadChunk(getWorld(), cx, cz, true);
|
||||
} else if (Settings.IMP.HISTORY.CHUNK_WAIT_MS > 0) {
|
||||
loadChunk.value = new IntegerPair(cx, cz);
|
||||
cachedLoadChunk = null;
|
||||
loadChunk.value.x = cx;
|
||||
loadChunk.value.z = cz;
|
||||
TaskManager.IMP.syncWhenFree(loadChunk, Settings.IMP.HISTORY.CHUNK_WAIT_MS);
|
||||
if (!isChunkLoaded(cx, cz)) {
|
||||
throw new FaweException.FaweChunkLoadException();
|
||||
}
|
||||
return cachedLoadChunk;
|
||||
} else {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return false;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return false;
|
||||
}
|
||||
@ -368,21 +392,24 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
}
|
||||
@ -394,24 +421,38 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (y >= FaweChunk.HEIGHT) {
|
||||
return 15;
|
||||
}
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
return getSkyLight(x, y + 16, z);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
if (lastSection == null) {
|
||||
if (lastChunkSections == null) {
|
||||
return 0;
|
||||
}
|
||||
int max = FaweChunk.HEIGHT >> 4;
|
||||
do {
|
||||
if (++cy >= max) {
|
||||
return 15;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} while (lastSection == null);
|
||||
}
|
||||
if (lastSection == null) {
|
||||
|
||||
return getSkyLight(x, y + 16, z);
|
||||
}
|
||||
return getSkyLight(lastSection, x, y, z);
|
||||
@ -422,19 +463,23 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
@ -447,21 +492,24 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
}
|
||||
@ -473,21 +521,24 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
}
|
||||
@ -499,21 +550,24 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
}
|
||||
@ -537,24 +591,69 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
|
||||
if (lastSection == null) {
|
||||
return 0;
|
||||
}
|
||||
return getCombinedId4Data(lastSection, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeId(int x, int z) throws FaweException.FaweChunkLoadException {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
lastSectionY = -1;
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return 0;
|
||||
}
|
||||
} else if (lastChunk == null) {
|
||||
return 0;
|
||||
}
|
||||
return getBiome(lastChunk, x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
lastSectionY = -1;
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return null;
|
||||
}
|
||||
} else if (lastChunk == null) {
|
||||
return null;
|
||||
}
|
||||
return getTileEntity(lastChunk, x, y, z);
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,15 @@ package com.boydti.fawe.example;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
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;
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> extends MappedFaweQueue<WORLD, CHUNKSECTION, SECTION> {
|
||||
public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> extends MappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> {
|
||||
|
||||
private final int maxY;
|
||||
|
||||
@ -60,10 +58,13 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
@Override
|
||||
public void end(FaweChunk chunk) {
|
||||
super.end(chunk);
|
||||
if (Settings.IMP.LIGHTING.MODE == 0 || !Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
if (Settings.IMP.LIGHTING.MODE == 0) {
|
||||
sendChunk(chunk);
|
||||
return;
|
||||
}
|
||||
if (!Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
sendChunk(chunk);
|
||||
}
|
||||
if (Settings.IMP.LIGHTING.MODE == 2) {
|
||||
relighter.addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||
return;
|
||||
@ -90,7 +91,7 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
}
|
||||
if (relight) {
|
||||
relighter.addChunk(chunk.getX(), chunk.getZ(), fix, chunk.getBitMask());
|
||||
} else {
|
||||
} else if (Settings.IMP.LIGHTING.DELAY_PACKET_SENDING) {
|
||||
sendChunk(chunk);
|
||||
}
|
||||
}
|
||||
@ -148,19 +149,23 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
if (lastSection == null) {
|
||||
return;
|
||||
@ -172,19 +177,23 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
int cy = y >> 4;
|
||||
if (cx != lastChunkX || cz != lastChunkZ) {
|
||||
lastChunkX = cx;
|
||||
lastChunkZ = cz;
|
||||
if (!ensureChunkLoaded(cx, cz)) {
|
||||
if (cx != lastSectionX || cz != lastSectionZ) {
|
||||
lastSectionX = cx;
|
||||
lastSectionZ = cz;
|
||||
lastChunk = ensureChunkLoaded(cx, cz);
|
||||
if (lastChunk != null) {
|
||||
lastChunkSections = getSections(lastChunk);
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else {
|
||||
lastChunkSections = null;
|
||||
return;
|
||||
}
|
||||
lastChunkSections = getCachedSections(getWorld(), cx, cz);
|
||||
} else if (cy != lastSectionY) {
|
||||
if (lastChunkSections != null) {
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
} else if (cy != lastChunkY) {
|
||||
if (lastChunkSections == null) {
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
lastSection = getCachedSection(lastChunkSections, cy);
|
||||
}
|
||||
if (lastSection == null) {
|
||||
return;
|
||||
@ -199,24 +208,4 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
public abstract void refreshChunk(FaweChunk fs);
|
||||
|
||||
public abstract CharFaweChunk getPrevious(CharFaweChunk fs, CHUNKSECTION sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception;
|
||||
|
||||
public abstract CompoundTag getTileEntity(CHUNK chunk, int x, int y, int z);
|
||||
|
||||
public abstract CHUNK getChunk(WORLD world, int x, int z);
|
||||
|
||||
private CHUNK lastChunk;
|
||||
|
||||
@Override
|
||||
public CompoundTag getTileEntity(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
if (y < 0 || y > maxY) {
|
||||
return null;
|
||||
}
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
lastChunk = getChunk(getWorld(), cx, cz);
|
||||
if (lastChunk == null) {
|
||||
return null;
|
||||
}
|
||||
return getTileEntity(lastChunk, x, y, z);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.IntegerTrio;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -14,15 +16,14 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class NMSRelighter implements Relighter{
|
||||
private final NMSMappedFaweQueue queue;
|
||||
|
||||
private final Map<Long, RelightSkyEntry> skyToRelight;
|
||||
private final Map<Long, Map<Short, Object>> lightQueue;
|
||||
private final Map<Long, Map<Integer, Object>> lightQueue;
|
||||
private final Object present = new Object();
|
||||
private final HashMap<Long, Integer> chunksToSend;
|
||||
private final Map<Long, Integer> chunksToSend;
|
||||
|
||||
private final int maxY;
|
||||
private volatile boolean relighting = false;
|
||||
@ -33,9 +34,9 @@ public class NMSRelighter implements Relighter{
|
||||
|
||||
public NMSRelighter(NMSMappedFaweQueue queue) {
|
||||
this.queue = queue;
|
||||
this.skyToRelight = new ConcurrentHashMap<>();
|
||||
this.lightQueue = new ConcurrentHashMap<>();
|
||||
chunksToSend = new HashMap<>();
|
||||
this.skyToRelight = new Long2ObjectOpenHashMap<>();
|
||||
this.lightQueue = new Long2ObjectOpenHashMap<>();
|
||||
this.chunksToSend = new Long2ObjectOpenHashMap<>();
|
||||
this.maxY = queue.getMaxY();
|
||||
}
|
||||
|
||||
@ -63,7 +64,6 @@ public class NMSRelighter implements Relighter{
|
||||
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = skyToRelight.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||
iter.remove();
|
||||
RelightSkyEntry chunk = entry.getValue();
|
||||
long pair = entry.getKey();
|
||||
Integer existing = chunksToSend.get(pair);
|
||||
@ -71,10 +71,11 @@ public class NMSRelighter implements Relighter{
|
||||
queue.ensureChunkLoaded(chunk.x, chunk.z);
|
||||
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
|
||||
queue.removeLighting(sections, FaweQueue.RelightMode.ALL, queue.hasSky());
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBlockLight(Map<Long, Map<Short, Object>> map) {
|
||||
public void updateBlockLight(Map<Long, Map<Integer, Object>> map) {
|
||||
int size = map.size();
|
||||
if (size == 0) {
|
||||
return;
|
||||
@ -84,17 +85,16 @@ public class NMSRelighter implements Relighter{
|
||||
Map<IntegerTrio, Object> visited = new HashMap<>();
|
||||
Map<IntegerTrio, Object> removalVisited = new HashMap<>();
|
||||
|
||||
Iterator<Map.Entry<Long, Map<Short, Object>>> iter = map.entrySet().iterator();
|
||||
Iterator<Map.Entry<Long, Map<Integer, Object>>> iter = map.entrySet().iterator();
|
||||
while (iter.hasNext() && size-- > 0) {
|
||||
Map.Entry<Long, Map<Short, Object>> entry = iter.next();
|
||||
iter.remove();
|
||||
Map.Entry<Long, Map<Integer, Object>> entry = iter.next();
|
||||
long index = entry.getKey();
|
||||
Map<Short, Object> blocks = entry.getValue();
|
||||
Map<Integer, Object> blocks = entry.getValue();
|
||||
int chunkX = MathMan.unpairIntX(index);
|
||||
int chunkZ = MathMan.unpairIntY(index);
|
||||
int bx = chunkX << 4;
|
||||
int bz = chunkZ << 4;
|
||||
for (short blockHash : blocks.keySet()) {
|
||||
for (int blockHash : blocks.keySet()) {
|
||||
int x = (blockHash >> 12 & 0xF) + bx;
|
||||
int y = (blockHash & 0xFF);
|
||||
int z = (blockHash >> 8 & 0xF) + bz;
|
||||
@ -114,6 +114,7 @@ public class NMSRelighter implements Relighter{
|
||||
}
|
||||
}
|
||||
}
|
||||
iter.remove();
|
||||
}
|
||||
|
||||
while (!lightRemovalQueue.isEmpty()) {
|
||||
@ -192,12 +193,12 @@ public class NMSRelighter implements Relighter{
|
||||
|
||||
public void addLightUpdate(int x, int y, int z) {
|
||||
long index = MathMan.pairInt((int) x >> 4, (int) z >> 4);
|
||||
Map<Short, Object> currentMap = lightQueue.get(index);
|
||||
Map<Integer, Object> currentMap = lightQueue.get(index);
|
||||
if (currentMap == null) {
|
||||
currentMap = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
currentMap = new Int2ObjectOpenHashMap<>();
|
||||
this.lightQueue.put(index, currentMap);
|
||||
}
|
||||
currentMap.put(MathMan.tripleBlockCoord(x, y, z), present);
|
||||
currentMap.put((int) MathMan.tripleBlockCoord(x, y, z), present);
|
||||
}
|
||||
|
||||
public synchronized void fixLightingSafe(boolean sky) {
|
||||
@ -222,10 +223,10 @@ public class NMSRelighter implements Relighter{
|
||||
Map.Entry<Long, Integer> entry = iter.next();
|
||||
long pair = entry.getKey();
|
||||
int bitMask = entry.getValue();
|
||||
iter.remove();
|
||||
int x = MathMan.unpairIntX(pair);
|
||||
int z = MathMan.unpairIntY(pair);
|
||||
queue.sendChunk(x, z, bitMask);
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@ -239,9 +240,9 @@ public class NMSRelighter implements Relighter{
|
||||
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = skyToRelight.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||
iter.remove();
|
||||
chunksToSend.put(entry.getKey(), entry.getValue().bitmask);
|
||||
chunksList.add(entry.getValue());
|
||||
iter.remove();
|
||||
}
|
||||
Collections.sort(chunksList);
|
||||
int size = chunksList.size();
|
||||
@ -312,7 +313,6 @@ public class NMSRelighter implements Relighter{
|
||||
int brightness = MathMan.unpair16y(pair);
|
||||
if (brightness > 1 && (brightness != 15 || opacity != 15)) {
|
||||
addLightUpdate(bx + x, y, bz + z);
|
||||
// lightBlock(bx + x, y, bz + z, brightness);
|
||||
}
|
||||
switch (value) {
|
||||
case 0:
|
||||
|
@ -11,6 +11,7 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
public class NullFaweChunk extends FaweChunk<Void> {
|
||||
public static final NullFaweChunk INSTANCE = new NullFaweChunk(null, 0 ,0);
|
||||
/**
|
||||
* A FaweSections object represents a chunk and the blocks that you wish to change in it.
|
||||
*
|
||||
@ -32,6 +33,11 @@ public class NullFaweChunk extends FaweChunk<Void> {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBiomeArray() {
|
||||
return new byte[256];
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitMask() {
|
||||
return 0;
|
||||
@ -92,6 +98,11 @@ public class NullFaweChunk extends FaweChunk<Void> {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, byte biome) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk<Void> copy(boolean shallow) {
|
||||
return this;
|
||||
|
@ -6,13 +6,13 @@ import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorCompletionService;
|
||||
|
||||
public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
@ -23,12 +23,14 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map of chunks in the queue
|
||||
*/
|
||||
public ConcurrentHashMap<Long, Reference<FaweChunk>> blocks = new ConcurrentHashMap<Long, Reference<FaweChunk>>(8, 0.9f, 1) {
|
||||
public final Long2ObjectOpenHashMap<Reference<FaweChunk>> blocks = new Long2ObjectOpenHashMap<Reference<FaweChunk>>() {
|
||||
@Override
|
||||
public Reference<FaweChunk> put(Long key, Reference<FaweChunk> value) {
|
||||
return put((long) key, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reference<FaweChunk> put(long key, Reference<FaweChunk> value) {
|
||||
if (parent.getProgressTask() != null) {
|
||||
try {
|
||||
parent.getProgressTask().run(FaweQueue.ProgressType.QUEUE, size() + 1);
|
||||
@ -36,8 +38,10 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
synchronized (this) {
|
||||
return super.put(key, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
@ -142,6 +146,7 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, ExecutorCompletionService pool, long time) {
|
||||
synchronized (blocks) {
|
||||
try {
|
||||
boolean skip = parent.getStage() == SetQueue.QueueStage.INACTIVE;
|
||||
int added = 0;
|
||||
@ -172,23 +177,21 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
}
|
||||
boolean result = true;
|
||||
// amount = 8;
|
||||
for (int i = 0; i < amount && (result = iter.hasNext()); i++, added++) {
|
||||
for (int i = 0; i < amount && (result = iter.hasNext());) {
|
||||
Map.Entry<Long, Reference<FaweChunk>> item = iter.next();
|
||||
Reference<FaweChunk> chunkReference = item.getValue();
|
||||
FaweChunk chunk = chunkReference.get();
|
||||
if (skip && chunk == lastWrappedChunk) {
|
||||
i--;
|
||||
added--;
|
||||
continue;
|
||||
}
|
||||
iter.remove();
|
||||
if (chunk != null) {
|
||||
parent.start(chunk);
|
||||
pool.submit(chunk);
|
||||
added++;
|
||||
i++;
|
||||
} else {
|
||||
Fawe.debug("Skipped modifying chunk due to low memory (4)");
|
||||
i--;
|
||||
added--;
|
||||
}
|
||||
}
|
||||
// if result, then submitted = amount
|
||||
@ -222,3 +225,4 @@ public class WeakFaweQueueMap implements IFaweQueueMap {
|
||||
return !blocks.isEmpty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import com.boydti.fawe.util.MathMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -241,9 +240,9 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, BaseBiome biome) {
|
||||
public void setBiome(int x, int z, byte biome) {
|
||||
modified = true;
|
||||
biomes[x + (z << 4)] = (byte) biome.getId();;
|
||||
biomes[x + (z << 4)] = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -292,6 +291,11 @@ public class MCAChunk extends FaweChunk<Void> {
|
||||
return id << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getBiomeArray() {
|
||||
return this.biomes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UUID> getEntityRemoves() {
|
||||
return new HashSet<>();
|
||||
|
@ -41,6 +41,32 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
this.hasSky = hasSky;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk loadChunk(FaweQueue faweQueue, int x, int z, boolean generate) {
|
||||
return getFaweChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getSections(FaweChunk faweChunk) {
|
||||
return faweChunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getCachedChunk(FaweQueue faweQueue, int cx, int cz) {
|
||||
return getFaweChunk(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(FaweChunk faweChunk, int x, int z) {
|
||||
if (faweChunk instanceof MCAChunk) {
|
||||
return ((MCAChunk) faweChunk).getBiomeArray()[((z & 0xF) << 4 | x & 0xF)];
|
||||
} else if (parent != null){
|
||||
return parent.getBiomeId(x, z);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void filterWorld(final MCAFilter filter) {
|
||||
File folder = getSaveFolder();
|
||||
final ForkJoinPool pool = new ForkJoinPool();
|
||||
@ -154,11 +180,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
throw new UnsupportedOperationException("Not supported");
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getChunk(FaweQueue faweQueue, int x, int z) {
|
||||
return (MCAChunk) getFaweChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweQueue getImpWorld() {
|
||||
return parent;
|
||||
@ -254,11 +275,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(FaweQueue faweQueue, int x, int z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FaweChunk getFaweChunk(int cx, int cz) {
|
||||
return getFaweQueueMap().getFaweChunk(cx, cz);
|
||||
@ -274,11 +290,6 @@ public class MCAQueue extends NMSMappedFaweQueue<FaweQueue, FaweChunk, FaweChunk
|
||||
return hasSky;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(FaweQueue faweQueue, int x, int z, boolean generate) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MCAChunk getCachedSections(FaweQueue faweQueue, int cx, int cz) {
|
||||
return (MCAChunk) getFaweQueueMap().getFaweChunk(cx, cz);
|
||||
|
@ -41,8 +41,14 @@ public class ChangeSetFaweQueue extends DelegateFaweQueue {
|
||||
|
||||
@Override
|
||||
public boolean setBiome(int x, int z, BaseBiome biome) {
|
||||
// TODO undo biome change
|
||||
return super.setBiome(x, z, biome);
|
||||
if (super.setBiome(x, z, biome)) {
|
||||
int oldBiome = getParent().getBiomeId(x, z);
|
||||
if (oldBiome != biome.getId()) {
|
||||
set.addBiomeChange(x, z, FaweCache.getBiome(oldBiome), biome);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -144,6 +144,8 @@ public abstract class FaweChunk<T> implements Callable<FaweChunk> {
|
||||
return ids;
|
||||
}
|
||||
|
||||
public abstract byte[] getBiomeArray();
|
||||
|
||||
public char[][] getCombinedIdArrays() {
|
||||
char[][] ids = new char[HEIGHT >> 4][];
|
||||
for (int y = 0; y < HEIGHT >> 4; y++) {
|
||||
@ -272,7 +274,11 @@ public abstract class FaweChunk<T> implements Callable<FaweChunk> {
|
||||
*/
|
||||
public abstract CompoundTag getTile(int x, int y, int z);
|
||||
|
||||
public abstract void setBiome(final int x, final int z, final BaseBiome biome);
|
||||
public void setBiome(final int x, final int z, final BaseBiome biome) {
|
||||
setBiome(x, z, (byte) biome.getId());
|
||||
}
|
||||
|
||||
public abstract void setBiome(final int x, final int z, final byte biome);
|
||||
|
||||
/**
|
||||
* Spend time now so that the chunk can be more efficiently dispatched later<br>
|
||||
|
@ -281,8 +281,6 @@ public abstract class FaweQueue {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean isChunkLoaded(final int x, final int z);
|
||||
|
||||
@Deprecated
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
return regenerateChunk(x, z, null, null);
|
||||
@ -349,6 +347,8 @@ public abstract class FaweQueue {
|
||||
return getCombinedId4Data(x, y, z) != 0;
|
||||
}
|
||||
|
||||
public abstract int getBiomeId(int x, int z) throws FaweException.FaweChunkLoadException;
|
||||
|
||||
public abstract int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException;
|
||||
|
||||
public abstract int getCachedCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException;
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.BaseEntity;
|
||||
@ -15,6 +16,7 @@ import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Location;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import javax.annotation.Nullable;
|
||||
@ -133,6 +135,17 @@ public class HistoryExtent extends AbstractDelegateExtent {
|
||||
return newList;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBiome(Vector2D position, BaseBiome newBiome) {
|
||||
BaseBiome oldBiome = this.getBiome(position);
|
||||
if (oldBiome.getId() != newBiome.getId()) {
|
||||
this.changeSet.addBiomeChange(position.getBlockX(), position.getBlockZ(), oldBiome, newBiome);
|
||||
return extent.setBiome(position, newBiome);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class TrackedEntity implements Entity {
|
||||
private final Entity entity;
|
||||
|
||||
|
@ -5,6 +5,7 @@ import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -47,6 +48,11 @@ public class NullChangeSet extends FaweChangeSet {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiomeChange(int x, int z, BaseBiome from, BaseBiome to) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addChangeTask(FaweQueue queue) {
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.boydti.fawe.object.brush;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
@ -176,7 +177,7 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
player.printError("No block in sight!");
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -216,7 +217,7 @@ public class DoubleActionBrushTool implements DoubleActionTraceTool {
|
||||
try {
|
||||
brush.build(action, editSession, target, material, size);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached.");
|
||||
player.printError("Max blocks change limit reached."); // Never happens
|
||||
} finally {
|
||||
if (bag != null) {
|
||||
bag.flushChanges();
|
||||
|
@ -12,6 +12,7 @@ import com.sk89q.worldedit.MaxChangedBlocksException;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ErodeBrush implements DoubleActionBrush {
|
||||
@ -130,7 +131,7 @@ public class ErodeBrush implements DoubleActionBrush {
|
||||
}
|
||||
|
||||
private void erosionIteration(int brushSize, int brushSizeSquared, int erodeFaces, FaweClipboard current, FaweClipboard target) {
|
||||
Map<Integer, Integer> frequency = Maps.newHashMap();
|
||||
Int2ObjectOpenHashMap<Integer> frequency = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
for (int x = -brushSize; x <= brushSize; x++) {
|
||||
for (int y = -brushSize; y <= brushSize; y++) {
|
||||
|
@ -42,12 +42,12 @@ public class HeightBrush implements DoubleActionBrush {
|
||||
|
||||
@Override
|
||||
public void build(DoubleActionBrushTool.BrushAction action, EditSession editSession, Vector position, Pattern pattern, double sizeDouble) throws MaxChangedBlocksException {
|
||||
int size = (int) (action == DoubleActionBrushTool.BrushAction.PRIMARY ? sizeDouble : -sizeDouble);
|
||||
int size = (int) sizeDouble;
|
||||
Mask mask = tool.getMask();
|
||||
if (mask == Masks.alwaysTrue() || mask == Masks.alwaysTrue2D()) {
|
||||
mask = null;
|
||||
}
|
||||
heightMap.setSize(size);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, yscale, true);
|
||||
heightMap.apply(editSession, mask, position, size, rotation, action == DoubleActionBrushTool.BrushAction.PRIMARY ? yscale : -yscale, true);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,36 @@
|
||||
package com.boydti.fawe.object.change;
|
||||
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.history.UndoContext;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
|
||||
public class MutableBiomeChange implements Change {
|
||||
|
||||
private Vector2D pos;
|
||||
private BaseBiome from;
|
||||
private BaseBiome to;
|
||||
public MutableBiomeChange() {
|
||||
this.from = new BaseBiome(0);
|
||||
this.to = new BaseBiome(0);
|
||||
this.pos = new Vector2D();
|
||||
}
|
||||
|
||||
public void setBiome(int x, int z, int from, int to) {
|
||||
this.pos.x = x;
|
||||
this.pos.z = z;
|
||||
this.from.setId(from);
|
||||
this.to.setId(to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undo(UndoContext context) throws WorldEditException {
|
||||
context.getExtent().setBiome(pos, from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void redo(UndoContext context) throws WorldEditException {
|
||||
context.getExtent().setBiome(pos, to);
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.history.change.EntityCreate;
|
||||
import com.sk89q.worldedit.history.change.EntityRemove;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class AbstractDelegateChangeSet extends FaweChangeSet {
|
||||
@ -71,6 +72,11 @@ public class AbstractDelegateChangeSet extends FaweChangeSet {
|
||||
return parent.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiomeChange(int x, int z, BaseBiome from, BaseBiome to) {
|
||||
parent.addBiomeChange(x, z, from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
parent.addTileCreate(tag);
|
||||
|
@ -8,6 +8,7 @@ import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
@ -56,6 +57,11 @@ public class CPUOptimizedChangeSet extends FaweChangeSet {
|
||||
throw new UnsupportedOperationException("Invalid mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiomeChange(int x, int z, BaseBiome from, BaseBiome to) {
|
||||
throw new UnsupportedOperationException("Invalid mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
throw new UnsupportedOperationException("Invalid mode");
|
||||
|
@ -13,13 +13,13 @@ import com.sk89q.jnbt.NBTInputStream;
|
||||
import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@ -34,6 +34,7 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
|
||||
private UUID uuid;
|
||||
private File bdFile;
|
||||
private File bioFile;
|
||||
private File nbtfFile;
|
||||
private File nbttFile;
|
||||
private File entfFile;
|
||||
@ -49,6 +50,8 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
* { short rel x, short rel z, unsigned byte y, short combinedFrom, short combinedTo }
|
||||
*/
|
||||
private OutputStream osBD;
|
||||
// biome
|
||||
private OutputStream osBIO;
|
||||
// NBT From
|
||||
private NBTOutputStream osNBTF;
|
||||
// NBT To
|
||||
@ -117,6 +120,7 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
entfFile = new File(folder, index + ".entf");
|
||||
enttFile = new File(folder, index + ".entt");
|
||||
bdFile = new File(folder, index + ".bd");
|
||||
bioFile = new File(folder, index + ".bio");
|
||||
}
|
||||
|
||||
private void init(UUID uuid, int i) {
|
||||
@ -165,12 +169,16 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
public boolean flush() {
|
||||
super.flush();
|
||||
synchronized (this) {
|
||||
boolean flushed = osBD != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null;
|
||||
boolean flushed = osBD != null || osBIO != null || osNBTF != null || osNBTT != null && osENTCF != null || osENTCT != null;
|
||||
try {
|
||||
if (osBD != null) {
|
||||
osBD.close();
|
||||
osBD = null;
|
||||
}
|
||||
if (osBIO != null) {
|
||||
osBIO.close();
|
||||
osBIO = null;
|
||||
}
|
||||
if (osNBTF != null) {
|
||||
osNBTF.close();
|
||||
osNBTF = null;
|
||||
@ -210,6 +218,9 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
if (bdFile.exists()) {
|
||||
total += bdFile.length();
|
||||
}
|
||||
if (bioFile.exists()) {
|
||||
total += bioFile.length();
|
||||
}
|
||||
if (nbtfFile.exists()) {
|
||||
total += entfFile.length();
|
||||
}
|
||||
@ -239,6 +250,19 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getBiomeOS() throws IOException {
|
||||
if (osBIO != null) {
|
||||
return osBIO;
|
||||
}
|
||||
synchronized (this) {
|
||||
bioFile.getParentFile().mkdirs();
|
||||
bioFile.createNewFile();
|
||||
osBIO = getCompressedOS(new FileOutputStream(bioFile));
|
||||
return osBIO;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTOutputStream getEntityCreateOS() throws IOException {
|
||||
if (osENTCT != null) {
|
||||
@ -293,6 +317,15 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
return is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBiomeIS() throws IOException {
|
||||
if (!bioFile.exists()) {
|
||||
return null;
|
||||
}
|
||||
InputStream is = MainUtil.getCompressedIS(new FileInputStream(bioFile));
|
||||
return is;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NBTInputStream getEntityCreateIS() throws IOException {
|
||||
if (!enttFile.exists()) {
|
||||
@ -426,25 +459,25 @@ public class DiskStorageHistory extends FaweStreamChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Integer, Integer> getBlocks() {
|
||||
HashMap<Integer, Integer> map = new HashMap<>();
|
||||
public Map<Integer, Integer> getBlocks() {
|
||||
Int2ObjectOpenHashMap<Integer> map = new Int2ObjectOpenHashMap<>();
|
||||
for (int i = 0; i < blocks.length; i++) {
|
||||
if (blocks[i] != 0) {
|
||||
map.put(i, blocks[i]);
|
||||
map.put(i, (Integer) blocks[i]);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public Map<Integer, Double> getPercents() {
|
||||
HashMap<Integer, Integer> map = getBlocks();
|
||||
Map<Integer, Integer> map = getBlocks();
|
||||
int count = getSize();
|
||||
HashMap<Integer, Double> newMap = new HashMap<Integer, Double>();
|
||||
Int2ObjectOpenHashMap<Double> newMap = new Int2ObjectOpenHashMap<Double>();
|
||||
for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
|
||||
int id = entry.getKey();
|
||||
int changes = entry.getValue();
|
||||
double percent = ((changes * 1000l) / count) / 10d;
|
||||
newMap.put(id, percent);
|
||||
newMap.put(id, (Double) percent);
|
||||
}
|
||||
return newMap;
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import com.sk89q.worldedit.history.change.EntityCreate;
|
||||
import com.sk89q.worldedit.history.change.EntityRemove;
|
||||
import com.sk89q.worldedit.history.changeset.ChangeSet;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -119,6 +120,7 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
public abstract void addTileRemove(CompoundTag tag);
|
||||
public abstract void addEntityRemove(CompoundTag tag);
|
||||
public abstract void addEntityCreate(CompoundTag tag);
|
||||
public abstract void addBiomeChange(int x, int z, BaseBiome from, BaseBiome to);
|
||||
public Iterator<Change> getIterator(BlockBag blockBag, int mode, boolean redo) {
|
||||
return getIterator(redo);
|
||||
}
|
||||
@ -227,15 +229,26 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
int cz = previous.getZ();
|
||||
int bx = cx << 4;
|
||||
int bz = cz << 4;
|
||||
synchronized (FaweChangeSet.this) {
|
||||
// Biome changes
|
||||
{
|
||||
if (previous.getBiomeArray() != null) {
|
||||
byte[] previousBiomes = previous.getBiomeArray();
|
||||
byte[] nextBiomes = next.getBiomeArray();
|
||||
int index = 0;
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int zz = bz + z;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
byte idFrom = previousBiomes[index];
|
||||
byte idTo = nextBiomes[index];
|
||||
if (idFrom != idTo && idTo != 0) {
|
||||
addBiomeChange(bx + x, zz, FaweCache.getBiome(idFrom & 0xFF), FaweCache.getBiome(idTo & 0xFF));
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
// TODO
|
||||
}
|
||||
// Block changes
|
||||
// Current blocks
|
||||
// char[][] currentIds = next.getCombinedIdArrays();
|
||||
// Previous blocks in modified sections (i.e. we skip sections that weren't modified)
|
||||
// char[][] previousIds = previous.getCombinedIdArrays();
|
||||
for (int layer = 0; layer < layers; layer++) {
|
||||
char[] currentLayer = next.getIdArray(layer);
|
||||
char[] previousLayer = previous.getIdArray(layer);
|
||||
@ -261,7 +274,6 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
default:
|
||||
char combinedIdPrevious = previousLayer != null ? previousLayer[index] : 0;
|
||||
if (combinedIdCurrent != combinedIdPrevious) {
|
||||
synchronized (FaweChangeSet.this) {
|
||||
add(xx, yy, zz, combinedIdPrevious, combinedIdCurrent);
|
||||
}
|
||||
}
|
||||
@ -269,37 +281,29 @@ public abstract class FaweChangeSet implements ChangeSet {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Tile changes
|
||||
{
|
||||
// Tiles created
|
||||
Map<Short, CompoundTag> tiles = next.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
|
||||
synchronized (FaweChangeSet.this) {
|
||||
addTileCreate(entry.getValue());
|
||||
}
|
||||
}
|
||||
// Tiles removed
|
||||
tiles = previous.getTiles();
|
||||
for (Map.Entry<Short, CompoundTag> entry : tiles.entrySet()) {
|
||||
synchronized (FaweChangeSet.this) {
|
||||
addTileRemove(entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
// Entity changes
|
||||
{
|
||||
// Entities created
|
||||
Set<CompoundTag> entities = next.getEntities();
|
||||
for (CompoundTag entityTag : entities) {
|
||||
synchronized (FaweChangeSet.this) {
|
||||
addEntityCreate(entityTag);
|
||||
}
|
||||
}
|
||||
// Entities removed
|
||||
entities = previous.getEntities();
|
||||
for (CompoundTag entityTag : entities) {
|
||||
synchronized (FaweChangeSet.this) {
|
||||
addEntityRemove(entityTag);
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package com.boydti.fawe.object.changeset;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweInputStream;
|
||||
import com.boydti.fawe.object.FaweOutputStream;
|
||||
import com.boydti.fawe.object.change.MutableBiomeChange;
|
||||
import com.boydti.fawe.object.change.MutableBlockChange;
|
||||
import com.boydti.fawe.object.change.MutableEntityChange;
|
||||
import com.boydti.fawe.object.change.MutableFullBlockChange;
|
||||
@ -15,12 +16,14 @@ import com.sk89q.jnbt.NBTOutputStream;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.history.change.Change;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
|
||||
@ -266,12 +269,14 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
}
|
||||
|
||||
public abstract OutputStream getBlockOS(int x, int y, int z) throws IOException;
|
||||
public abstract OutputStream getBiomeOS() throws IOException;
|
||||
public abstract NBTOutputStream getEntityCreateOS() throws IOException;
|
||||
public abstract NBTOutputStream getEntityRemoveOS() throws IOException;
|
||||
public abstract NBTOutputStream getTileCreateOS() throws IOException;
|
||||
public abstract NBTOutputStream getTileRemoveOS() throws IOException;
|
||||
|
||||
public abstract InputStream getBlockIS() throws IOException;
|
||||
public abstract InputStream getBiomeIS() throws IOException;
|
||||
public abstract NBTInputStream getEntityCreateIS() throws IOException;
|
||||
public abstract NBTInputStream getEntityRemoveIS() throws IOException;
|
||||
public abstract NBTInputStream getTileCreateIS() throws IOException;
|
||||
@ -312,10 +317,32 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addBiomeChange(int x, int z, BaseBiome from, BaseBiome to) {
|
||||
blockSize++;
|
||||
try {
|
||||
OutputStream os = getBiomeOS();
|
||||
os.write((byte) (x >> 24));
|
||||
os.write((byte) (x >> 16));
|
||||
os.write((byte) (x >> 8));
|
||||
os.write((byte) (x));
|
||||
os.write((byte) (z >> 24));
|
||||
os.write((byte) (z >> 16));
|
||||
os.write((byte) (z >> 8));
|
||||
os.write((byte) (z));
|
||||
os.write(from.getId());
|
||||
os.write(to.getId());
|
||||
}
|
||||
catch (Throwable e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
}
|
||||
|
||||
public void addTileCreate(CompoundTag tag) {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getTileCreateOS();
|
||||
nbtos.writeTag(tag);
|
||||
@ -328,6 +355,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getTileRemoveOS();
|
||||
nbtos.writeTag(tag);
|
||||
@ -340,6 +368,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getEntityRemoveOS();
|
||||
nbtos.writeTag(tag);
|
||||
@ -352,6 +381,7 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
if (tag == null) {
|
||||
return;
|
||||
}
|
||||
blockSize++;
|
||||
try {
|
||||
NBTOutputStream nbtos = getEntityCreateOS();
|
||||
nbtos.writeTag(tag);
|
||||
@ -376,32 +406,83 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
idDel.readCombined(is, change, dir);
|
||||
return change;
|
||||
} catch (EOFException ignoreOEF) {
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (last != null) {
|
||||
return true;
|
||||
} else if ((last = read()) != null) {
|
||||
return true;
|
||||
return last != null || ((last = read()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBlockChange next() {
|
||||
MutableBlockChange tmp = last;
|
||||
if (tmp == null) {
|
||||
tmp = read();
|
||||
}
|
||||
last = null;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new IllegalArgumentException("CANNOT REMOVE");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public Iterator<MutableBiomeChange> getBiomeIterator(final boolean dir) throws IOException {
|
||||
final InputStream is = getBiomeIS();
|
||||
if (is == null) {
|
||||
return new ArrayList<MutableBiomeChange>().iterator();
|
||||
}
|
||||
final MutableBiomeChange change = new MutableBiomeChange();
|
||||
return new Iterator<MutableBiomeChange>() {
|
||||
private MutableBiomeChange last = new MutableBiomeChange();
|
||||
public MutableBiomeChange read() {
|
||||
try {
|
||||
int int1 = is.read();
|
||||
if (int1 != -1) {
|
||||
int x = ((int1 << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0));
|
||||
int z = ((is.read() << 24) + (is.read() << 16) + (is.read() << 8) + (is.read() << 0));
|
||||
int from = is.read();
|
||||
int to = is.read();
|
||||
change.setBiome(x, z, from, to);
|
||||
return change;
|
||||
}
|
||||
} catch (EOFException ignoreOEF) {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBlockChange next() {
|
||||
MutableBlockChange tmp = last;
|
||||
public boolean hasNext() {
|
||||
return last != null || ((last = read()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableBiomeChange next() {
|
||||
MutableBiomeChange tmp = last;
|
||||
if (tmp == null) {
|
||||
tmp = read();
|
||||
}
|
||||
last = null;
|
||||
return tmp;
|
||||
}
|
||||
@ -441,8 +522,13 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
idDel.readCombined(is, change, dir);
|
||||
return change;
|
||||
} catch (EOFException ignoreOEF) {
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return null;
|
||||
@ -450,23 +536,15 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (last == null) {
|
||||
last = read();
|
||||
}
|
||||
if (last != null) {
|
||||
return true;
|
||||
}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return false;
|
||||
return last != null || ((last = read()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableFullBlockChange next() {
|
||||
MutableFullBlockChange tmp = last;
|
||||
if (tmp == null) {
|
||||
tmp = read();
|
||||
}
|
||||
last = null;
|
||||
return tmp;
|
||||
}
|
||||
@ -485,36 +563,35 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
final MutableEntityChange change = new MutableEntityChange(null, create);
|
||||
try {
|
||||
return new Iterator<MutableEntityChange>() {
|
||||
private CompoundTag last = read();
|
||||
private MutableEntityChange last = read();
|
||||
|
||||
public CompoundTag read() {
|
||||
public MutableEntityChange read() {
|
||||
try {
|
||||
return (CompoundTag) is.readTag();
|
||||
} catch (Exception ignoreEOS) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (last == null) {
|
||||
last = read();
|
||||
}
|
||||
if (last != null) {
|
||||
return true;
|
||||
}
|
||||
CompoundTag tag = (CompoundTag) is.readTag();
|
||||
change.tag = tag;
|
||||
return change;
|
||||
} catch (Exception ignoreOEF) {}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return last != null || ((last = read()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableEntityChange next() {
|
||||
change.tag = last;
|
||||
MutableEntityChange tmp = last;
|
||||
if (tmp == null) {
|
||||
tmp = read();
|
||||
}
|
||||
last = null;
|
||||
return change;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -535,36 +612,35 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
final MutableTileChange change = new MutableTileChange(null, create);
|
||||
try {
|
||||
return new Iterator<MutableTileChange>() {
|
||||
private CompoundTag last = read();
|
||||
private MutableTileChange last = read();
|
||||
|
||||
public CompoundTag read() {
|
||||
public MutableTileChange read() {
|
||||
try {
|
||||
return (CompoundTag) is.readTag();
|
||||
} catch (Exception ignoreEOS) {}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
if (last == null) {
|
||||
last = read();
|
||||
}
|
||||
if (last != null) {
|
||||
return true;
|
||||
}
|
||||
CompoundTag tag = (CompoundTag) is.readTag();
|
||||
change.tag = tag;
|
||||
return change;
|
||||
} catch (Exception ignoreOEF) {}
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
MainUtil.handleError(e);
|
||||
}
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return last != null || ((last = read()) != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MutableTileChange next() {
|
||||
change.tag = last;
|
||||
MutableTileChange tmp = last;
|
||||
if (tmp == null) {
|
||||
tmp = read();
|
||||
}
|
||||
last = null;
|
||||
return change;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -589,8 +665,10 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
|
||||
final Iterator<MutableBlockChange> blockChange = getBlockIterator(dir);
|
||||
|
||||
final Iterator<MutableBiomeChange> biomeChange = getBiomeIterator(dir);
|
||||
|
||||
return new Iterator<Change>() {
|
||||
Iterator<Change>[] iterators = new Iterator[]{tileCreate, tileRemove, entityCreate, entityRemove, blockChange};
|
||||
Iterator<Change>[] iterators = new Iterator[]{tileCreate, tileRemove, entityCreate, entityRemove, blockChange, biomeChange};
|
||||
int i = 0;
|
||||
Iterator<Change> current = iterators[0];
|
||||
|
||||
@ -613,7 +691,15 @@ public abstract class FaweStreamChangeSet extends FaweChangeSet {
|
||||
|
||||
@Override
|
||||
public Change next() {
|
||||
try {
|
||||
return current.next();
|
||||
} catch (Throwable ignore) {
|
||||
if (i >= iterators.length - 1) {
|
||||
throw new NoSuchElementException("End of iterator");
|
||||
}
|
||||
current = iterators[++i];
|
||||
return next();
|
||||
}
|
||||
}
|
||||
};
|
||||
} catch (Exception e) {
|
||||
|
@ -21,11 +21,14 @@ import java.io.OutputStream;
|
||||
*/
|
||||
public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
||||
|
||||
private int size = 0;
|
||||
private byte[][] ids;
|
||||
private FastByteArrayOutputStream idsStream;
|
||||
private FaweOutputStream idsStreamZip;
|
||||
|
||||
private byte[][] biomes;
|
||||
private FastByteArrayOutputStream biomeStream;
|
||||
private FaweOutputStream biomeStreamZip;
|
||||
|
||||
private byte[][] entC;
|
||||
private FastByteArrayOutputStream entCStream;
|
||||
private NBTOutputStream entCStreamZip;
|
||||
@ -57,11 +60,16 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
||||
try {
|
||||
if (idsStream != null) {
|
||||
idsStreamZip.close();
|
||||
size = idsStream.getSize();
|
||||
ids = idsStream.toByteArrays();
|
||||
idsStream = null;
|
||||
idsStreamZip = null;
|
||||
}
|
||||
if (biomeStream != null) {
|
||||
biomeStreamZip.close();
|
||||
biomes = biomeStream.toByteArrays();
|
||||
biomeStream = null;
|
||||
biomeStreamZip = null;
|
||||
}
|
||||
if (entCStream != null) {
|
||||
entCStreamZip.close();
|
||||
entC = entCStream.toByteArrays();
|
||||
@ -125,6 +133,27 @@ public class MemoryOptimizedHistory extends FaweStreamChangeSet {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBiomeIS() throws IOException {
|
||||
if (biomes == null) {
|
||||
return null;
|
||||
}
|
||||
FaweInputStream result = MainUtil.getCompressedIS(new FastByteArraysInputStream(biomes));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public OutputStream getBiomeOS() throws IOException {
|
||||
if (biomeStreamZip != null) {
|
||||
return biomeStreamZip;
|
||||
}
|
||||
synchronized (this) {
|
||||
biomeStream = new FastByteArrayOutputStream(Settings.IMP.HISTORY.BUFFER_SIZE);
|
||||
biomeStreamZip = getCompressedOS(biomeStream);
|
||||
return biomeStreamZip;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBlockIS() throws IOException {
|
||||
if (ids == null) {
|
||||
|
@ -10,7 +10,6 @@ import com.sk89q.jnbt.DoubleTag;
|
||||
import com.sk89q.jnbt.ListTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -85,10 +84,7 @@ public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFa
|
||||
|
||||
@Override
|
||||
public BaseBiome getBiome(final Vector2D position) {
|
||||
if (!queue.isChunkLoaded(position.getBlockX() >> 4, position.getBlockZ() >> 4)) {
|
||||
return EditSession.nullBiome;
|
||||
}
|
||||
return super.getBiome(position);
|
||||
return FaweCache.CACHE_BIOME[queue.getBiomeId(position.getBlockX(), position.getBlockZ())];
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,12 +53,11 @@ public class FuzzyRegion extends AbstractRegion {
|
||||
public Iterator<BlockVector> iterator() {
|
||||
return new Iterator<BlockVector>() {
|
||||
|
||||
private int index = -1;
|
||||
private int index = set.nextSetBit(0);
|
||||
private BlockVector pos = new BlockVector(0, 0, 0);
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
index = set.nextSetBit(index + 1);
|
||||
return index != -1;
|
||||
}
|
||||
|
||||
@ -71,6 +70,7 @@ public class FuzzyRegion extends AbstractRegion {
|
||||
pos.mutX(offsetX + (((b3 + ((MathMan.unpair8x(b2)) << 8)) << 21) >> 21));
|
||||
pos.mutY(offsetY + b1);
|
||||
pos.mutZ(offsetZ + (((b4 + ((MathMan.unpair8y(b2)) << 8)) << 21) >> 21));
|
||||
index = set.nextSetBit(index + 1);
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class PlotTrim implements Listener {
|
||||
}
|
||||
|
||||
public void setChunk(int x, int z) {
|
||||
this.ids = originalQueue.getChunk(originalQueue, x, z).ids;
|
||||
this.ids = ((MCAChunk) originalQueue.getFaweChunk(x, z)).ids;
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.Relighter;
|
||||
import com.boydti.fawe.object.FaweChunk;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
@ -7,6 +9,10 @@ import com.boydti.fawe.object.RunnableVal2;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
@ -49,6 +55,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
parent.addEditSession(session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public World getWEWorld() {
|
||||
return parent.getWEWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProgressTracker(RunnableVal2<ProgressType, Integer> progressTask) {
|
||||
parent.setProgressTracker(progressTask);
|
||||
@ -89,6 +100,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
parent.setProgressTask(progressTask);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiomeId(int x, int z) throws FaweException.FaweChunkLoadException {
|
||||
return parent.getBiomeId(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChangeTask(RunnableVal2<FaweChunk, FaweChunk> changeTask) {
|
||||
parent.setChangeTask(changeTask);
|
||||
@ -104,11 +120,26 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
parent.optimize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(CuboidRegion cuboid, int id, int data) {
|
||||
return parent.setBlocks(cuboid, id, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, int id, int data) {
|
||||
return parent.setBlock(x, y, z, id, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, int id) {
|
||||
return parent.setBlock(x, y, z, id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setBlock(int x, int y, int z, int id, int data, CompoundTag nbt) {
|
||||
return parent.setBlock(x, y, z, id, data, nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTile(int x, int y, int z, CompoundTag tag) {
|
||||
parent.setTile(x, y, z, tag);
|
||||
@ -150,8 +181,24 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(int x, int z) {
|
||||
return parent.isChunkLoaded(x, z);
|
||||
public int getMaxY() {
|
||||
return parent.getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachBlockInChunk(int cx, int cz, RunnableVal2<Vector, BaseBlock> onEach) {
|
||||
parent.forEachBlockInChunk(cx, cz, onEach);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachTileInChunk(int cx, int cz, RunnableVal2<Vector, BaseBlock> onEach) {
|
||||
parent.forEachTileInChunk(cx, cz, onEach);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
return parent.regenerateChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -179,6 +226,7 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
parent.sendBlockUpdate(blockMap, players);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
@Override
|
||||
public boolean next() {
|
||||
return parent.next();
|
||||
@ -209,6 +257,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
parent.addNotifyTask(x, z, runnable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBlock(int x, int y, int z) throws FaweException.FaweChunkLoadException {
|
||||
return parent.hasBlock(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNotifyTask(Runnable runnable) {
|
||||
parent.addNotifyTask(runnable);
|
||||
@ -224,6 +277,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
return parent.getCachedCombinedId4Data(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getAdjacentLight(int x, int y, int z) {
|
||||
return parent.getAdjacentLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasSky() {
|
||||
return parent.hasSky();
|
||||
@ -234,6 +292,11 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
return parent.getSkyLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLight(int x, int y, int z) {
|
||||
return parent.getLight(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEmmittedLight(int x, int y, int z) {
|
||||
return parent.getEmmittedLight(x, y, z);
|
||||
@ -249,23 +312,98 @@ public class DelegateFaweQueue extends FaweQueue {
|
||||
return parent.getCombinedId4Data(x, y, z, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCachedCombinedId4Data(int x, int y, int z, int def) {
|
||||
return parent.getCachedCombinedId4Data(x, y, z, def);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCombinedId4DataDebug(int x, int y, int z, int def, EditSession session) {
|
||||
return parent.getCombinedId4DataDebug(x, y, z, def, session);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBrightness(int x, int y, int z) {
|
||||
return parent.getBrightness(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacityBrightnessPair(int x, int y, int z) {
|
||||
return parent.getOpacityBrightnessPair(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOpacity(int x, int y, int z) {
|
||||
return parent.getOpacity(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return parent.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return parent.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() {
|
||||
parent.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SetQueue.QueueStage getStage() {
|
||||
return parent.getStage();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setStage(SetQueue.QueueStage stage) {
|
||||
parent.setStage(stage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush(int time) {
|
||||
parent.flush(time);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTasks() {
|
||||
parent.runTasks();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addTask(Runnable whenFree) {
|
||||
parent.addTask(whenFree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean enqueue() {
|
||||
return parent.enqueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dequeue() {
|
||||
parent.dequeue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Relighter getRelighter() {
|
||||
return parent.getRelighter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Settings getSettings() {
|
||||
return parent.getSettings();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSettings(Settings settings) {
|
||||
parent.setSettings(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setWorld(String world) {
|
||||
parent.setWorld(world);
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
package com.boydti.fawe.util;
|
||||
|
||||
import com.sk89q.worldedit.event.extent.EditSessionEvent;
|
||||
import com.sk89q.worldedit.util.eventbus.EventHandler.Priority;
|
||||
import com.sk89q.worldedit.util.eventbus.Subscribe;
|
||||
|
||||
public class WESubscriber {
|
||||
|
||||
@Subscribe(priority = Priority.VERY_EARLY)
|
||||
public void onEditSession(final EditSessionEvent event) {}
|
||||
}
|
@ -72,7 +72,6 @@ import com.sk89q.worldedit.extent.AbstractDelegateExtent;
|
||||
import com.sk89q.worldedit.extent.ChangeSetExtent;
|
||||
import com.sk89q.worldedit.extent.Extent;
|
||||
import com.sk89q.worldedit.extent.MaskingExtent;
|
||||
import com.sk89q.worldedit.extent.buffer.ForgetfulExtentBuffer;
|
||||
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||
import com.sk89q.worldedit.extent.world.SurvivalModeExtent;
|
||||
import com.sk89q.worldedit.function.GroundFunction;
|
||||
@ -92,7 +91,6 @@ import com.sk89q.worldedit.function.mask.RegionMask;
|
||||
import com.sk89q.worldedit.function.operation.ChangeSetExecutor;
|
||||
import com.sk89q.worldedit.function.operation.ForwardExtentCopy;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
import com.sk89q.worldedit.function.operation.OperationQueue;
|
||||
import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.BlockPattern;
|
||||
import com.sk89q.worldedit.function.pattern.Patterns;
|
||||
@ -1543,6 +1541,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
public boolean canBypassAll(Region region, boolean get, boolean set) {
|
||||
if (wrapped) return false;
|
||||
FaweRegionExtent regionExtent = getRegionExtent();
|
||||
if (!(region instanceof CuboidRegion)) return false;
|
||||
if (regionExtent != null) {
|
||||
if (!(region instanceof CuboidRegion)) return false;
|
||||
Vector pos1 = region.getMinimumPoint();
|
||||
@ -1950,7 +1949,11 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
checkNotNull(dir);
|
||||
checkArgument(distance >= 1, "distance >= 1 required");
|
||||
final Vector displace = dir.multiply(distance);
|
||||
// Remove the original blocks
|
||||
|
||||
final Vector size = region.getMaximumPoint().subtract(region.getMinimumPoint()).add(1, 1, 1);
|
||||
final Vector to = region.getMinimumPoint();
|
||||
final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, EditSession.this, to);
|
||||
|
||||
final com.sk89q.worldedit.function.pattern.Pattern pattern = replacement != null ? new BlockPattern(replacement) : new BlockPattern(new BaseBlock(BlockID.AIR));
|
||||
final BlockReplace remove = new BlockReplace(EditSession.this, pattern) {
|
||||
@Override
|
||||
@ -1966,12 +1969,9 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
}
|
||||
};
|
||||
|
||||
// Copy to a buffer so we don't destroy our original before we can copy all the blocks from it
|
||||
final ForgetfulExtentBuffer buffer = new ForgetfulExtentBuffer(EditSession.this, new RegionMask(region));
|
||||
final ForwardExtentCopy copy = new ForwardExtentCopy(EditSession.this, region, buffer, region.getMinimumPoint());
|
||||
copy.setSourceFunction(remove);
|
||||
copy.setRepetitions(1);
|
||||
copy.setTransform(new AffineTransform().translate(dir.multiply(distance)));
|
||||
copy.setSourceFunction(remove); // Remove
|
||||
copy.setRemovingEntities(true);
|
||||
Mask sourceMask = getSourceMask();
|
||||
if (sourceMask != null) {
|
||||
new MaskTraverser(sourceMask).reset(EditSession.this);
|
||||
@ -1981,13 +1981,7 @@ public class EditSession extends AbstractWorld implements HasFaweQueue, Lighting
|
||||
if (!copyAir) {
|
||||
copy.setSourceMask(new ExistingBlockMask(EditSession.this));
|
||||
}
|
||||
|
||||
// Then we need to copy the buffer to the world
|
||||
final BlockReplace replace = new BlockReplace(EditSession.this, buffer);
|
||||
final RegionVisitor visitor = new RegionVisitor(buffer.asRegion(), replace);
|
||||
|
||||
final OperationQueue operation = new OperationQueue(copy, visitor);
|
||||
Operations.completeSmart(operation, new Runnable() {
|
||||
Operations.completeSmart(copy, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
EditSession.this.flushQueue();
|
||||
|
670
core/src/main/java/com/sk89q/worldedit/Vector2D.java
Normal file
670
core/src/main/java/com/sk89q/worldedit/Vector2D.java
Normal file
@ -0,0 +1,670 @@
|
||||
/*
|
||||
* WorldEdit, a Minecraft world manipulation toolkit
|
||||
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||
* Copyright (C) WorldEdit team and contributors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.sk89q.worldedit;
|
||||
|
||||
import com.sk89q.worldedit.math.transform.AffineTransform;
|
||||
|
||||
/**
|
||||
* An immutable 2-dimensional vector.
|
||||
*/
|
||||
public class Vector2D {
|
||||
public static final Vector2D ZERO = new Vector2D(0, 0);
|
||||
public static final Vector2D UNIT_X = new Vector2D(1, 0);
|
||||
public static final Vector2D UNIT_Z = new Vector2D(0, 1);
|
||||
public static final Vector2D ONE = new Vector2D(1, 1);
|
||||
|
||||
public double x, z;
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param z the Z coordinate
|
||||
*/
|
||||
public Vector2D(double x, double z) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param z the Z coordinate
|
||||
*/
|
||||
public Vector2D(int x, int z) {
|
||||
this.x = (double) x;
|
||||
this.z = (double) z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an instance.
|
||||
*
|
||||
* @param x the X coordinate
|
||||
* @param z the Z coordinate
|
||||
*/
|
||||
public Vector2D(float x, float z) {
|
||||
this.x = (double) x;
|
||||
this.z = (double) z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy another vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
*/
|
||||
public Vector2D(Vector2D other) {
|
||||
this.x = other.x;
|
||||
this.z = other.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new instance with X and Z coordinates set to 0.
|
||||
*
|
||||
* <p>One can also refer to a static {@link #ZERO}.</p>
|
||||
*/
|
||||
public Vector2D() {
|
||||
this.x = 0;
|
||||
this.z = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X coordinate.
|
||||
*
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the X coordinate rounded.
|
||||
*
|
||||
* @return the x coordinate
|
||||
*/
|
||||
public int getBlockX() {
|
||||
return (int) Math.round(x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the X coordinate.
|
||||
*
|
||||
* @param x the new X
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D setX(double x) {
|
||||
return new Vector2D(x, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the X coordinate.
|
||||
*
|
||||
* @param x the new X
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D setX(int x) {
|
||||
return new Vector2D(x, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z coordinate.
|
||||
*
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Z coordinate rounded.
|
||||
*
|
||||
* @return the z coordinate
|
||||
*/
|
||||
public int getBlockZ() {
|
||||
return (int) Math.round(z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Z coordinate.
|
||||
*
|
||||
* @param z the new Z
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D setZ(double z) {
|
||||
return new Vector2D(x, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Z coordinate.
|
||||
*
|
||||
* @param z the new Z
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D setZ(int z) {
|
||||
return new Vector2D(x, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another vector to this vector and return the result as a new vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D add(Vector2D other) {
|
||||
return new Vector2D(x + other.x, z + other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another vector to this vector and return the result as a new vector.
|
||||
*
|
||||
* @param x the value to add
|
||||
* @param z the value to add
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D add(double x, double z) {
|
||||
return new Vector2D(this.x + x, this.z + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add another vector to this vector and return the result as a new vector.
|
||||
*
|
||||
* @param x the value to add
|
||||
* @param z the value to add
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D add(int x, int z) {
|
||||
return new Vector2D(this.x + x, this.z + z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a list of vectors to this vector and return the
|
||||
* result as a new vector.
|
||||
*
|
||||
* @param others an array of vectors
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D add(Vector2D... others) {
|
||||
double newX = x, newZ = z;
|
||||
|
||||
for (Vector2D other : others) {
|
||||
newX += other.x;
|
||||
newZ += other.z;
|
||||
}
|
||||
|
||||
return new Vector2D(newX, newZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D subtract(Vector2D other) {
|
||||
return new Vector2D(x - other.x, z - other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
*
|
||||
* @param x the value to subtract
|
||||
* @param z the value to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D subtract(double x, double z) {
|
||||
return new Vector2D(this.x - x, this.z - z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract another vector from this vector and return the result
|
||||
* as a new vector.
|
||||
*
|
||||
* @param x the value to subtract
|
||||
* @param z the value to subtract
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D subtract(int x, int z) {
|
||||
return new Vector2D(this.x - x, this.z - z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a list of vectors from this vector and return the result
|
||||
* as a new vector.
|
||||
*
|
||||
* @param others an array of vectors
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D subtract(Vector2D... others) {
|
||||
double newX = x, newZ = z;
|
||||
|
||||
for (Vector2D other : others) {
|
||||
newX -= other.x;
|
||||
newZ -= other.z;
|
||||
}
|
||||
|
||||
return new Vector2D(newX, newZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this vector by another vector on each component.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(Vector2D other) {
|
||||
return new Vector2D(x * other.x, z * other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this vector by another vector on each component.
|
||||
*
|
||||
* @param x the value to multiply
|
||||
* @param z the value to multiply
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(double x, double z) {
|
||||
return new Vector2D(this.x * x, this.z * z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this vector by another vector on each component.
|
||||
*
|
||||
* @param x the value to multiply
|
||||
* @param z the value to multiply
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(int x, int z) {
|
||||
return new Vector2D(this.x * x, this.z * z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiply this vector by zero or more vectors on each component.
|
||||
*
|
||||
* @param others an array of vectors
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(Vector2D... others) {
|
||||
double newX = x, newZ = z;
|
||||
|
||||
for (Vector2D other : others) {
|
||||
newX *= other.x;
|
||||
newZ *= other.z;
|
||||
}
|
||||
|
||||
return new Vector2D(newX, newZ);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar multiplication and return a new vector.
|
||||
*
|
||||
* @param n the value to multiply
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(double n) {
|
||||
return new Vector2D(this.x * n, this.z * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar multiplication and return a new vector.
|
||||
*
|
||||
* @param n the value to multiply
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(float n) {
|
||||
return new Vector2D(this.x * n, this.z * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar multiplication and return a new vector.
|
||||
*
|
||||
* @param n the value to multiply
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D multiply(int n) {
|
||||
return new Vector2D(this.x * n, this.z * n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide this vector by another vector on each component.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(Vector2D other) {
|
||||
return new Vector2D(x / other.x, z / other.z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide this vector by another vector on each component.
|
||||
*
|
||||
* @param x the value to divide by
|
||||
* @param z the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(double x, double z) {
|
||||
return new Vector2D(this.x / x, this.z / z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Divide this vector by another vector on each component.
|
||||
*
|
||||
* @param x the value to divide by
|
||||
* @param z the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(int x, int z) {
|
||||
return new Vector2D(this.x / x, this.z / z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar division and return a new vector.
|
||||
*
|
||||
* @param n the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(int n) {
|
||||
return new Vector2D(x / n, z / n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar division and return a new vector.
|
||||
*
|
||||
* @param n the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(double n) {
|
||||
return new Vector2D(x / n, z / n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform scalar division and return a new vector.
|
||||
*
|
||||
* @param n the value to divide by
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D divide(float n) {
|
||||
return new Vector2D(x / n, z / n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length of the vector.
|
||||
*
|
||||
* @return length
|
||||
*/
|
||||
public double length() {
|
||||
return Math.sqrt(x * x + z * z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the length, squared, of the vector.
|
||||
*
|
||||
* @return length, squared
|
||||
*/
|
||||
public double lengthSq() {
|
||||
return x * x + z * z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance between this vector and another vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return distance
|
||||
*/
|
||||
public double distance(Vector2D other) {
|
||||
return Math.sqrt(Math.pow(other.x - x, 2) + Math.pow(other.z - z, 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the distance between this vector and another vector, squared.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return distance
|
||||
*/
|
||||
public double distanceSq(Vector2D other) {
|
||||
return Math.pow(other.x - x, 2) +
|
||||
Math.pow(other.z - z, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the normalized vector, which is the vector divided by its
|
||||
* length, as a new vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D normalize() {
|
||||
return divide(length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the dot product of this and another vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return the dot product of this and the other vector
|
||||
*/
|
||||
public double dot(Vector2D other) {
|
||||
return x * other.x + z * other.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a vector is contained with another.
|
||||
*
|
||||
* @param min the minimum point (X, Y, and Z are the lowest)
|
||||
* @param max the maximum point (X, Y, and Z are the lowest)
|
||||
* @return true if the vector is contained
|
||||
*/
|
||||
public boolean containedWithin(Vector2D min, Vector2D max) {
|
||||
return x >= min.x && x <= max.x
|
||||
&& z >= min.z && z <= max.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks to see if a vector is contained with another.
|
||||
*
|
||||
* @param min the minimum point (X, Y, and Z are the lowest)
|
||||
* @param max the maximum point (X, Y, and Z are the lowest)
|
||||
* @return true if the vector is contained
|
||||
*/
|
||||
public boolean containedWithinBlock(Vector2D min, Vector2D max) {
|
||||
return getBlockX() >= min.getBlockX() && getBlockX() <= max.getBlockX()
|
||||
&& getBlockZ() >= min.getBlockZ() && getBlockZ() <= max.getBlockZ();
|
||||
}
|
||||
|
||||
/**
|
||||
* Floors the values of all components.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D floor() {
|
||||
return new Vector2D(Math.floor(x), Math.floor(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds all components up.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D ceil() {
|
||||
return new Vector2D(Math.ceil(x), Math.ceil(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds all components to the closest integer.
|
||||
*
|
||||
* <p>Components < 0.5 are rounded down, otherwise up.</p>
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D round() {
|
||||
return new Vector2D(Math.floor(x + 0.5), Math.floor(z + 0.5));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a vector with the absolute values of the components of
|
||||
* this vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector2D positive() {
|
||||
return new Vector2D(Math.abs(x), Math.abs(z));
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a 2D transformation on this vector and return a new one.
|
||||
*
|
||||
* @param angle in degrees
|
||||
* @param aboutX about which x coordinate to rotate
|
||||
* @param aboutZ about which z coordinate to rotate
|
||||
* @param translateX what to add after rotation
|
||||
* @param translateZ what to add after rotation
|
||||
* @return a new vector
|
||||
* @see AffineTransform another method to transform vectors
|
||||
*/
|
||||
public Vector2D transform2D(double angle, double aboutX, double aboutZ, double translateX, double translateZ) {
|
||||
angle = Math.toRadians(angle);
|
||||
double x = this.x - aboutX;
|
||||
double z = this.z - aboutZ;
|
||||
double x2 = x * Math.cos(angle) - z * Math.sin(angle);
|
||||
double z2 = x * Math.sin(angle) + z * Math.cos(angle);
|
||||
return new Vector2D(
|
||||
x2 + aboutX + translateX,
|
||||
z2 + aboutZ + translateZ
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this vector is collinear with another vector.
|
||||
*
|
||||
* @param other the other vector
|
||||
* @return true if collinear
|
||||
*/
|
||||
public boolean isCollinearWith(Vector2D other) {
|
||||
if (x == 0 && z == 0) {
|
||||
// this is a zero vector
|
||||
return true;
|
||||
}
|
||||
|
||||
final double otherX = other.x;
|
||||
final double otherZ = other.z;
|
||||
|
||||
if (otherX == 0 && otherZ == 0) {
|
||||
// other is a zero vector
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((x == 0) != (otherX == 0)) return false;
|
||||
if ((z == 0) != (otherZ == 0)) return false;
|
||||
|
||||
final double quotientX = otherX / x;
|
||||
if (!Double.isNaN(quotientX)) {
|
||||
return other.equals(multiply(quotientX));
|
||||
}
|
||||
|
||||
final double quotientZ = otherZ / z;
|
||||
if (!Double.isNaN(quotientZ)) {
|
||||
return other.equals(multiply(quotientZ));
|
||||
}
|
||||
|
||||
throw new RuntimeException("This should not happen");
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@code BlockVector2D} from this vector.
|
||||
*
|
||||
* @return a new {@code BlockVector2D}
|
||||
*/
|
||||
public BlockVector2D toBlockVector2D() {
|
||||
return new BlockVector2D(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 3D vector by adding a zero Y component to this vector.
|
||||
*
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector toVector() {
|
||||
return new Vector(x, 0, z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a 3D vector by adding the specified Y component to this vector.
|
||||
*
|
||||
* @param y the Y component
|
||||
* @return a new vector
|
||||
*/
|
||||
public Vector toVector(double y) {
|
||||
return new Vector(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof Vector2D)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Vector2D other = (Vector2D) obj;
|
||||
return other.x == this.x && other.z == this.z;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((new Double(x)).hashCode() >> 13) ^
|
||||
(new Double(z)).hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "(" + x + ", " + z + ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum components of two vectors.
|
||||
*
|
||||
* @param v1 the first vector
|
||||
* @param v2 the second vector
|
||||
* @return minimum
|
||||
*/
|
||||
public static Vector2D getMinimum(Vector2D v1, Vector2D v2) {
|
||||
return new Vector2D(
|
||||
Math.min(v1.x, v2.x),
|
||||
Math.min(v1.z, v2.z)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum components of two vectors.
|
||||
*
|
||||
* @param v1 the first vector
|
||||
* @param v2 the second vector
|
||||
* @return maximum
|
||||
*/
|
||||
public static Vector2D getMaximum(Vector2D v1, Vector2D v2) {
|
||||
return new Vector2D(
|
||||
Math.max(v1.x, v2.x),
|
||||
Math.max(v1.z, v2.z)
|
||||
);
|
||||
}
|
||||
|
||||
public static Class<?> inject() {
|
||||
return Vector2D.class;
|
||||
}
|
||||
}
|
@ -94,7 +94,7 @@ public class BiomeCommands {
|
||||
BiomeRegistry biomeRegistry = player.getWorld().getWorldData().getBiomeRegistry();
|
||||
List<BaseBiome> biomes = biomeRegistry.getBiomes();
|
||||
int totalPages = biomes.size() / 19 + 1;
|
||||
player.print(BBC.getPrefix() + "Available Biomes (page " + page + "/" + totalPages + ") :");
|
||||
BBC.BIOME_LIST_HEADER.send(player, page, totalPages);
|
||||
for (BaseBiome biome : biomes) {
|
||||
if (offset > 0) {
|
||||
offset--;
|
||||
@ -106,7 +106,7 @@ public class BiomeCommands {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
player.print(BBC.getPrefix() + " <unknown #" + biome.getId() + ">");
|
||||
player.print(BBC.getPrefix() + " <? #" + biome.getId() + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,19 +132,15 @@ public class BiomeCommands {
|
||||
if (args.hasFlag('t')) {
|
||||
Vector blockPosition = player.getBlockTrace(300);
|
||||
if (blockPosition == null) {
|
||||
player.printError("No block in sight!");
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
BaseBiome biome = player.getWorld().getBiome(blockPosition.toVector2D());
|
||||
biomes.add(biome);
|
||||
|
||||
qualifier = "at line of sight point";
|
||||
} else if (args.hasFlag('p')) {
|
||||
BaseBiome biome = player.getWorld().getBiome(player.getPosition().toVector2D());
|
||||
biomes.add(biome);
|
||||
|
||||
qualifier = "at your position";
|
||||
} else {
|
||||
World world = player.getWorld();
|
||||
Region region = session.getSelection(world);
|
||||
@ -158,17 +154,15 @@ public class BiomeCommands {
|
||||
biomes.add(world.getBiome(pt.toVector2D()));
|
||||
}
|
||||
}
|
||||
|
||||
qualifier = "in your selection";
|
||||
}
|
||||
|
||||
player.print(biomes.size() != 1 ? "Biomes " + qualifier + ":" : "Biome " + qualifier + ":");
|
||||
BBC.BIOME_LIST_HEADER.send(player, 1, 1);
|
||||
for (BaseBiome biome : biomes) {
|
||||
BiomeData data = biomeRegistry.getData(biome);
|
||||
if (data != null) {
|
||||
player.print(BBC.getPrefix() + " " + data.getName());
|
||||
} else {
|
||||
player.print(BBC.getPrefix() + " <unknown #" + biome.getId() + ">");
|
||||
player.print(BBC.getPrefix() + " <? #" + biome.getId() + ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -204,7 +198,7 @@ public class BiomeCommands {
|
||||
FlatRegionVisitor visitor = new FlatRegionVisitor(Regions.asFlatRegion(region), replace);
|
||||
Operations.completeLegacy(visitor);
|
||||
|
||||
player.print(BBC.getPrefix() + "Biomes were changed in " + visitor.getAffected() + " columns. You may have to rejoin your game (or close and reopen your world) to see a change.");
|
||||
BBC.BIOME_CHANGED.send(player, visitor.getAffected());
|
||||
}
|
||||
|
||||
public static Class<BiomeCommands> inject() {
|
||||
|
@ -438,7 +438,7 @@ public class BrushCommands {
|
||||
maxRadius = Math.max(config.maxBrushRadius, config.butcherMaxRadius);
|
||||
}
|
||||
if (radius > maxRadius) {
|
||||
player.printError("Maximum allowed brush radius: " + maxRadius);
|
||||
BBC.TOOL_RADIUS_ERROR.send(player, maxRadius);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,6 @@ import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||
import com.sk89q.worldedit.entity.Entity;
|
||||
import com.sk89q.worldedit.entity.Player;
|
||||
import com.sk89q.worldedit.extension.platform.Actor;
|
||||
import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.Clipboard;
|
||||
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormat;
|
||||
@ -233,7 +232,7 @@ public class ClipboardCommands {
|
||||
public void download(final Player player, final LocalSession session, @Optional("schematic") final String formatName) throws CommandException, WorldEditException {
|
||||
final ClipboardFormat format = ClipboardFormat.findByAlias(formatName);
|
||||
if (format == null) {
|
||||
player.printError("Unknown schematic format: " + formatName);
|
||||
BBC.CLIPBOARD_INVALID_FORMAT.send(player, formatName);
|
||||
return;
|
||||
}
|
||||
ClipboardHolder holder = session.getClipboard();
|
||||
@ -467,32 +466,6 @@ public class ClipboardCommands {
|
||||
BBC.COMMAND_FLIPPED.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/load" },
|
||||
usage = "<filename>",
|
||||
desc = "Load a schematic into your clipboard",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@Deprecated
|
||||
@CommandPermissions("worldedit.clipboard.load")
|
||||
public void load(Actor actor) {
|
||||
actor.printError("This command is no longer used. See //schematic load.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/save" },
|
||||
usage = "<filename>",
|
||||
desc = "Save a schematic into your clipboard",
|
||||
min = 0,
|
||||
max = 1
|
||||
)
|
||||
@Deprecated
|
||||
@CommandPermissions("worldedit.clipboard.save")
|
||||
public void save(Actor actor) {
|
||||
actor.printError("This command is no longer used. See //schematic save.");
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "clearclipboard" },
|
||||
usage = "",
|
||||
|
@ -8,7 +8,6 @@ import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||
import com.sk89q.minecraft.util.commands.CommandPermissions;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
@ -55,36 +54,6 @@ public class GeneralCommands {
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/limit" },
|
||||
usage = "<limit>",
|
||||
desc = "Modify block change limit",
|
||||
min = 1,
|
||||
max = 1
|
||||
)
|
||||
@CommandPermissions("worldedit.limit")
|
||||
public void limit(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
|
||||
LocalConfiguration config = worldEdit.getConfiguration();
|
||||
boolean mayDisable = player.hasPermission("worldedit.limit.unrestricted");
|
||||
|
||||
int limit = Math.max(-1, args.getInteger(0));
|
||||
if (!mayDisable && config.maxChangeLimit > -1) {
|
||||
if (limit > config.maxChangeLimit) {
|
||||
player.printError("Your maximum allowable limit is " + config.maxChangeLimit + ".");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
session.setBlockChangeLimit(limit);
|
||||
|
||||
if (limit != -1) {
|
||||
player.print(BBC.getPrefix() + "Block change limit set to " + limit + ". (Use //limit -1 to go back to the default.)");
|
||||
} else {
|
||||
player.print(BBC.getPrefix() + "Block change limit set to " + limit + ".");
|
||||
}
|
||||
}
|
||||
|
||||
@Command(
|
||||
aliases = { "/fast" },
|
||||
usage = "[on|off]",
|
||||
@ -98,20 +67,20 @@ public class GeneralCommands {
|
||||
String newState = args.getString(0, null);
|
||||
if (session.hasFastMode()) {
|
||||
if ("on".equals(newState)) {
|
||||
player.printError("Fast mode already enabled.");
|
||||
BBC.FAST_ENABLED.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
session.setFastMode(false);
|
||||
player.print(BBC.getPrefix() + "Fast mode disabled.");
|
||||
BBC.FAST_DISABLED.send(player);
|
||||
} else {
|
||||
if ("off".equals(newState)) {
|
||||
player.printError("Fast mode already disabled.");
|
||||
BBC.FAST_DISABLED.send(player);
|
||||
return;
|
||||
}
|
||||
|
||||
session.setFastMode(true);
|
||||
player.print(BBC.getPrefix() + "Fast mode enabled. Lighting in the affected chunks may be wrong and/or you may need to rejoin to see changes.");
|
||||
BBC.FAST_ENABLED.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,9 +166,9 @@ public class GeneralCommands {
|
||||
public void togglePlace(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
|
||||
if (session.togglePlacementPosition()) {
|
||||
player.print(BBC.getPrefix() + "Now placing at pos #1.");
|
||||
BBC.PLACE_ENABLED.send(player);
|
||||
} else {
|
||||
player.print(BBC.getPrefix() + "Now placing at the block you stand in.");
|
||||
BBC.PLACE_DISABLED.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +119,7 @@ public class GenerationCommands {
|
||||
|
||||
Vector pos = session.getPlacementPosition(player);
|
||||
int affected = editSession.makeCylinder(pos, Patterns.wrap(pattern), radiusX, radiusZ, height, !hollow);
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -185,7 +185,7 @@ public class GenerationCommands {
|
||||
|
||||
int affected = editSession.makeSphere(pos, Patterns.wrap(pattern), radiusX, radiusY, radiusZ, !hollow);
|
||||
player.findFreePosition();
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -201,7 +201,7 @@ public class GenerationCommands {
|
||||
public void forestGen(Player player, LocalSession session, EditSession editSession, @Optional("10") int size, @Optional("tree") TreeType type, @Optional("5") double density) throws WorldEditException {
|
||||
density = density / 100;
|
||||
int affected = editSession.makeForest(session.getPlacementPosition(player), size, density, new TreeGenerator(type));
|
||||
player.print(BBC.getPrefix() + affected + " trees created.");
|
||||
BBC.COMMAND_TREE.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -215,7 +215,7 @@ public class GenerationCommands {
|
||||
@Logging(POSITION)
|
||||
public void pumpkins(Player player, LocalSession session, EditSession editSession, @Optional("10") int apothem) throws WorldEditException {
|
||||
int affected = editSession.makePumpkinPatches(session.getPlacementPosition(player), apothem);
|
||||
player.print(BBC.getPrefix() + affected + " pumpkin patches created.");
|
||||
BBC.COMMAND_PUMPKIN.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -246,7 +246,7 @@ public class GenerationCommands {
|
||||
worldEdit.checkMaxRadius(size);
|
||||
int affected = editSession.makePyramid(pos, Patterns.wrap(pattern), size, !hollow);
|
||||
player.findFreePosition();
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -309,7 +309,7 @@ public class GenerationCommands {
|
||||
try {
|
||||
final int affected = editSession.makeShape(region, zero, unit, Patterns.wrap(pattern), expression, hollow);
|
||||
player.findFreePosition();
|
||||
player.print(BBC.getPrefix() + affected + " block(s) have been created.");
|
||||
BBC.VISITOR_BLOCK.send(player, affected);
|
||||
} catch (ExpressionException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
@ -374,7 +374,7 @@ public class GenerationCommands {
|
||||
try {
|
||||
final int affected = editSession.makeBiomeShape(region, zero, unit, target, expression, hollow);
|
||||
player.findFreePosition();
|
||||
player.print(BBC.getPrefix() + "" + affected + " columns affected.");
|
||||
BBC.VISITOR_FLAT.send(player, affected);
|
||||
} catch (ExpressionException e) {
|
||||
player.printError(e.getMessage());
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ public class HistoryCommands {
|
||||
player.checkPermission("worldedit.history.undo.other");
|
||||
LocalSession sess = worldEdit.getSession(args.getString(1));
|
||||
if (sess == null) {
|
||||
player.printError("Unable to find session for " + args.getString(1));
|
||||
BBC.COMMAND_HISTORY_OTHER_ERROR.send(player, args.getString(1));
|
||||
break;
|
||||
}
|
||||
undone = sess.undo(session.getBlockBag(player), player);
|
||||
@ -257,7 +257,7 @@ public class HistoryCommands {
|
||||
player.checkPermission("worldedit.history.redo.other");
|
||||
LocalSession sess = worldEdit.getSession(args.getString(1));
|
||||
if (sess == null) {
|
||||
player.printError("Unable to find session for " + args.getString(1));
|
||||
BBC.COMMAND_HISTORY_OTHER_ERROR.send(player, args.getString(1));
|
||||
break;
|
||||
}
|
||||
redone = sess.redo(session.getBlockBag(player), player);
|
||||
|
@ -185,7 +185,7 @@ public class NavigationCommands {
|
||||
player.findFreePosition(pos);
|
||||
BBC.POOF.send(player);
|
||||
} else {
|
||||
BBC.JUMPTO_FAIL.send(player);
|
||||
BBC.NO_BLOCK.send(player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -789,7 +789,7 @@ public class SelectionCommands {
|
||||
|
||||
if (found != null) {
|
||||
session.setDefaultRegionSelector(found);
|
||||
player.print(BBC.getPrefix() + "Your default region selector is now " + found.name() + ".");
|
||||
BBC.SELECTOR_SET_DEFAULT.send(player, found.name());
|
||||
} else {
|
||||
throw new RuntimeException("Something unexpected happened. Please report this.");
|
||||
}
|
||||
|
@ -77,12 +77,12 @@ public class SnapshotCommands {
|
||||
|
||||
int num = args.argsLength() > 0 ? Math.min(40, Math.max(5, args.getInteger(0))) : 5;
|
||||
|
||||
player.print(BBC.getPrefix() + "Snapshots for world: '" + player.getWorld().getName() + "'");
|
||||
BBC.SNAPSHOT_LIST_HEADER.send(player, player.getWorld().getName());
|
||||
for (byte i = 0; i < Math.min(num, snapshots.size()); i++) {
|
||||
player.print(BBC.getPrefix() + (i + 1) + ". " + snapshots.get(i).getName());
|
||||
}
|
||||
|
||||
player.print(BBC.getPrefix() + "Use /snap use [snapshot] or /snap use latest.");
|
||||
BBC.SNAPSHOT_LIST_FOOTER.send(player);
|
||||
} else {
|
||||
player.printError("No snapshots are available. See console for details.");
|
||||
|
||||
@ -129,7 +129,7 @@ public class SnapshotCommands {
|
||||
|
||||
if (snapshot != null) {
|
||||
session.setSnapshot(null);
|
||||
player.print(BBC.getPrefix() + "Now using newest snapshot.");
|
||||
BBC.SNAPSHOT_NEWEST.send(player);
|
||||
} else {
|
||||
player.printError("No snapshots were found.");
|
||||
}
|
||||
@ -139,7 +139,7 @@ public class SnapshotCommands {
|
||||
} else {
|
||||
try {
|
||||
session.setSnapshot(config.snapshotRepo.getSnapshot(name));
|
||||
player.print(BBC.getPrefix() + "Snapshot set to: " + name);
|
||||
BBC.SNAPSHOT_SET.send(player, name);
|
||||
} catch (InvalidSnapshotException e) {
|
||||
player.printError("That snapshot does not exist or is not available.");
|
||||
}
|
||||
@ -187,7 +187,7 @@ public class SnapshotCommands {
|
||||
return;
|
||||
}
|
||||
session.setSnapshot(snapshot);
|
||||
player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName());
|
||||
BBC.SNAPSHOT_SET.send(player, snapshot.getName());
|
||||
} catch (MissingWorldException e) {
|
||||
player.printError("No snapshots were found for this world.");
|
||||
}
|
||||
@ -224,7 +224,7 @@ public class SnapshotCommands {
|
||||
+ dateFormat.format(date.getTime()) + ".");
|
||||
} else {
|
||||
session.setSnapshot(snapshot);
|
||||
player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName());
|
||||
BBC.SNAPSHOT_SET.send(player, snapshot.getName());
|
||||
}
|
||||
} catch (MissingWorldException ex) {
|
||||
player.printError("No snapshots were found for this world.");
|
||||
@ -258,11 +258,10 @@ public class SnapshotCommands {
|
||||
Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date, player.getWorld().getName());
|
||||
if (snapshot == null) {
|
||||
dateFormat.setTimeZone(session.getTimeZone());
|
||||
player.printError("Couldn't find a snapshot after "
|
||||
+ dateFormat.format(date.getTime()) + ".");
|
||||
player.printError("Couldn't find a snapshot after " + dateFormat.format(date.getTime()) + ".");
|
||||
} else {
|
||||
session.setSnapshot(snapshot);
|
||||
player.print(BBC.getPrefix() + "Snapshot set to: " + snapshot.getName());
|
||||
BBC.SNAPSHOT_SET.send(player, snapshot.getName());
|
||||
}
|
||||
} catch (MissingWorldException ex) {
|
||||
player.printError("No snapshots were found for this world.");
|
||||
|
@ -115,7 +115,7 @@ public class SnapshotUtilCommands {
|
||||
// Load chunk store
|
||||
try {
|
||||
chunkStore = snapshot.getChunkStore();
|
||||
player.print(BBC.getPrefix() + "Snapshot '" + snapshot.getName() + "' loaded; now restoring...");
|
||||
BBC.SNAPSHOT_LOADED.send(player, snapshot.getName());
|
||||
} catch (DataException e) {
|
||||
player.printError("Failed to load snapshot: " + e.getMessage());
|
||||
return;
|
||||
|
@ -48,7 +48,7 @@ public class SuperPickaxeCommands {
|
||||
|
||||
session.setSuperPickaxe(new SinglePickaxe());
|
||||
session.enableSuperPickAxe();
|
||||
player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable.");
|
||||
BBC.SUPERPICKAXE_AREA_ENABLED.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -65,13 +65,13 @@ public class SuperPickaxeCommands {
|
||||
int range = args.getInteger(0);
|
||||
|
||||
if (range > config.maxSuperPickaxeSize) {
|
||||
player.printError("Maximum range: " + config.maxSuperPickaxeSize);
|
||||
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
|
||||
return;
|
||||
}
|
||||
|
||||
session.setSuperPickaxe(new AreaPickaxe(range));
|
||||
session.enableSuperPickAxe();
|
||||
player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable.");
|
||||
BBC.SUPERPICKAXE_AREA_ENABLED.send(player);
|
||||
}
|
||||
|
||||
@Command(
|
||||
@ -88,13 +88,13 @@ public class SuperPickaxeCommands {
|
||||
double range = args.getDouble(0);
|
||||
|
||||
if (range > config.maxSuperPickaxeSize) {
|
||||
player.printError("Maximum range: " + config.maxSuperPickaxeSize);
|
||||
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
|
||||
return;
|
||||
}
|
||||
|
||||
session.setSuperPickaxe(new RecursivePickaxe(range));
|
||||
session.enableSuperPickAxe();
|
||||
player.print(BBC.getPrefix() + "Mode changed. Left click with a pickaxe. // to disable.");
|
||||
BBC.SUPERPICKAXE_AREA_ENABLED.send(player);
|
||||
}
|
||||
|
||||
public static Class<SuperPickaxeCommands> inject() {
|
||||
|
@ -155,7 +155,7 @@ public class ToolCommands {
|
||||
int range = args.getInteger(1);
|
||||
|
||||
if (range > config.maxSuperPickaxeSize) {
|
||||
BBC.TOOL_FLOOD_FILL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
|
||||
BBC.TOOL_RANGE_ERROR.send(player, config.maxSuperPickaxeSize);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -442,7 +442,7 @@ public class UtilityCommands {
|
||||
killed += visitor.getAffected();
|
||||
}
|
||||
|
||||
actor.print(BBC.getPrefix() + "Killed " + killed + (killed != 1 ? " mobs" : " mob") + (radius < 0 ? "" : " in a radius of " + radius) + ".");
|
||||
BBC.KILL_SUCCESS.send(actor, killed, radius);
|
||||
|
||||
if (editSession != null) {
|
||||
session.remember(editSession);
|
||||
@ -502,7 +502,7 @@ public class UtilityCommands {
|
||||
removed += visitor.getAffected();
|
||||
}
|
||||
|
||||
actor.print(BBC.getPrefix() + "Marked " + removed + (removed != 1 ? " entities" : " entity") + " for removal.");
|
||||
BBC.KILL_SUCCESS.send(removed, radius);
|
||||
|
||||
if (editSession != null) {
|
||||
session.remember(editSession);
|
||||
|
@ -107,9 +107,8 @@ public class WorldEditCommands {
|
||||
public void tz(Player player, LocalSession session, CommandContext args) throws WorldEditException {
|
||||
TimeZone tz = TimeZone.getTimeZone(args.getString(0));
|
||||
session.setTimezone(tz);
|
||||
player.print(BBC.getPrefix() + "Timezone set for this session to: " + tz.getDisplayName());
|
||||
player.print(BBC.getPrefix() + "The current time in that timezone is: "
|
||||
+ dateFormat.format(Calendar.getInstance(tz).getTime()));
|
||||
BBC.TIMEZONE_SET.send(player, tz.getDisplayName());
|
||||
BBC.TIMEZONE_DISPLAY.send(player, dateFormat.format(Calendar.getInstance(tz).getTime()));
|
||||
}
|
||||
|
||||
@Command(
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.sk89q.worldedit.command.tool;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.object.extent.ResettableExtent;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
@ -176,7 +177,7 @@ public class BrushTool implements TraceTool {
|
||||
target = player.getBlockTrace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
player.printError("No block in sight!");
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -216,7 +217,7 @@ public class BrushTool implements TraceTool {
|
||||
try {
|
||||
brush.build(editSession, target, material, size);
|
||||
} catch (MaxChangedBlocksException e) {
|
||||
player.printError("Max blocks change limit reached.");
|
||||
player.printError("Max blocks change limit reached."); // Never happens
|
||||
} finally {
|
||||
if (bag != null) {
|
||||
bag.flushChanges();
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
package com.sk89q.worldedit.command.tool;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.LocalConfiguration;
|
||||
import com.sk89q.worldedit.LocalSession;
|
||||
@ -82,7 +83,7 @@ public class LongRangeBuildTool extends BrushTool implements DoubleActionTraceTo
|
||||
target = player.getBlockTraceFace(getRange(), true);
|
||||
|
||||
if (target == null) {
|
||||
player.printError("No block in sight!");
|
||||
BBC.NO_BLOCK.send(player);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ package com.sk89q.worldedit.extension.factory;
|
||||
import com.boydti.fawe.jnbt.JSON2NBT;
|
||||
import com.boydti.fawe.jnbt.NBTException;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.intellectualcrafters.plot.util.StringMan;
|
||||
import com.boydti.fawe.util.StringMan;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.BlockVector;
|
||||
|
@ -282,19 +282,19 @@ public class DefaultMaskParser extends FaweParser<Mask> {
|
||||
int requiredMin = 1;
|
||||
int requiredMax = 8;
|
||||
if (split.length == 2) {
|
||||
String[] split2 = split[1].split(":");
|
||||
String[] split2 = split[1].split("[:|,]");
|
||||
requiredMin = (int) Math.abs(Expression.compile(split2[0]).evaluate());
|
||||
if (split2.length == 2) {
|
||||
if (split2.length >= 2) {
|
||||
requiredMax = (int) Math.abs(Expression.compile(split2[1]).evaluate());
|
||||
}
|
||||
}
|
||||
if (firstChar == '~') {
|
||||
return new AdjacentMask(extent, worldEdit.getBlockFactory().parseFromListInput(input.substring(1), tempContext), requiredMin, requiredMax);
|
||||
return new AdjacentMask(extent, worldEdit.getBlockFactory().parseFromListInput(split[0], tempContext), requiredMin, requiredMax);
|
||||
} else {
|
||||
return new WallMask(extent, worldEdit.getBlockFactory().parseFromListInput(input.substring(1), tempContext), requiredMin, requiredMax);
|
||||
}
|
||||
} catch (NumberFormatException | ExpressionException e) {
|
||||
throw new SuggestInputParseException(input, "~<blocks>=<amount>");
|
||||
throw new SuggestInputParseException(input, "~<blocks>=<min>:<max>");
|
||||
}
|
||||
}
|
||||
case '>':
|
||||
|
@ -482,7 +482,7 @@ public class PlatformManager {
|
||||
if (pos != null) {
|
||||
player.findFreePosition(pos);
|
||||
} else {
|
||||
player.printError("No block in sight (or too far)!");
|
||||
BBC.NO_BLOCK.send(player);
|
||||
}
|
||||
|
||||
event.setCancelled(true);
|
||||
|
@ -28,8 +28,8 @@ import com.sk89q.worldedit.Vector;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
import com.sk89q.worldedit.world.storage.ChunkStore;
|
||||
import java.util.AbstractSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
@ -315,18 +315,60 @@ public class CuboidRegion extends AbstractRegion implements FlatRegion {
|
||||
|
||||
@Override
|
||||
public Set<Vector2D> getChunks() {
|
||||
Set<Vector2D> chunks = new LinkedHashSet<Vector2D>();
|
||||
|
||||
Vector min = getMinimumPoint();
|
||||
Vector max = getMaximumPoint();
|
||||
final int maxX = max.getBlockX() >> ChunkStore.CHUNK_SHIFTS;
|
||||
final int minX = min.getBlockX() >> ChunkStore.CHUNK_SHIFTS;
|
||||
final int maxZ = max.getBlockZ() >> ChunkStore.CHUNK_SHIFTS;
|
||||
final int minZ = min.getBlockZ() >> ChunkStore.CHUNK_SHIFTS;
|
||||
final int size = (maxX - minX + 1) * (maxZ - minZ + 1);
|
||||
|
||||
for (int x = max.getBlockX() >> ChunkStore.CHUNK_SHIFTS; x >= min.getBlockX() >> ChunkStore.CHUNK_SHIFTS; --x) {
|
||||
for (int z = max.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; z >= min.getBlockZ() >> ChunkStore.CHUNK_SHIFTS; --z) {
|
||||
chunks.add(new Vector2D(x, z));
|
||||
}
|
||||
return new AbstractSet<Vector2D>() {
|
||||
@Override
|
||||
public Iterator<Vector2D> iterator() {
|
||||
return new Iterator<Vector2D>() {
|
||||
private Vector2D pos = new Vector2D(minX, minZ);
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return pos != null;
|
||||
}
|
||||
|
||||
return chunks;
|
||||
@Override
|
||||
public Vector2D next() {
|
||||
Vector2D result = pos;
|
||||
// calc next
|
||||
if (pos.getX() < maxX) {
|
||||
pos = new Vector2D(pos.getX() + 1, pos.getZ());
|
||||
} else if (pos.getZ() < maxZ) {
|
||||
pos = new Vector2D(minX, pos.getZ() + 1);
|
||||
} else {
|
||||
pos = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("This set is immutable.");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
if (o instanceof Vector2D) {
|
||||
Vector2D cv = (Vector2D) o;
|
||||
return cv.getX() >= minX && cv.getX() <= maxX && cv.getZ() >= minZ && cv.getZ() <= maxZ;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -58,6 +58,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -57,6 +57,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ jar.enabled = false
|
||||
shadowJar {
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(name: 'worldedit-core-6.1.4-SNAPSHOT-dist'))
|
||||
include(dependency('com.google.code.gson:gson:2.2.4'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
|
@ -28,9 +28,6 @@ public class FaweNukkit implements IFawe, Listener {
|
||||
private final NukkitWorldEdit plugin;
|
||||
|
||||
public FaweNukkit(NukkitWorldEdit mod) {
|
||||
Settings.IMP.HISTORY.USE_DISK = true;
|
||||
Settings.IMP.CLIPBOARD.USE_DISK = true;
|
||||
Settings.IMP.HISTORY.COMPRESSION_LEVEL = 9;
|
||||
this.plugin = mod;
|
||||
FaweChunk.HEIGHT = 128;
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
|
@ -14,7 +14,6 @@ import com.boydti.fawe.util.MainUtil;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.Vector2D;
|
||||
import com.sk89q.worldedit.world.biome.BaseBiome;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
@ -80,28 +79,18 @@ public class NukkitChunk extends CharFaweChunk<BaseFullChunk, NukkitQueue> {
|
||||
final BaseFullChunk chunk = getChunk();
|
||||
getParent().setHeightMap(this, heightMap);
|
||||
char[][] sections = getCombinedIdArrays();
|
||||
final int[][] biomes = getBiomeArray();
|
||||
final int X = getX() << 4;
|
||||
final int Z = getZ() << 4;
|
||||
if (biomes != null) {
|
||||
final LocalWorld lw = NukkitUtil.getLocalWorld(world);
|
||||
final BaseBiome bb = new BaseBiome(0);
|
||||
int last = 0;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
final int[] array = biomes[x];
|
||||
if (array == null) {
|
||||
continue;
|
||||
}
|
||||
final byte[] biomes = getBiomeArray();
|
||||
int index = 0;
|
||||
Vector2D mutable = new Vector2D();
|
||||
for (int z = 0; z < 16; z++) {
|
||||
final int biome = array[z];
|
||||
if (biome == 0) {
|
||||
continue;
|
||||
}
|
||||
if (last != biome) {
|
||||
last = biome;
|
||||
bb.setId(biome);
|
||||
}
|
||||
lw.setBiome(new Vector2D(X + x, Z + z), bb);
|
||||
mutable.z = Z + z;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
mutable.x = X + x;
|
||||
lw.setBiome(mutable, FaweCache.getBiome(biomes[index++] & 0xFF));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -236,21 +236,11 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
||||
return NBTConverter.fromNative(nbt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseFullChunk getChunk(Level level, int x, int z) {
|
||||
return (BaseFullChunk) level.getChunk(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Level getImpWorld() {
|
||||
return world;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChunkLoaded(Level level, int x, int z) {
|
||||
return level.isChunkLoaded(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean regenerateChunk(Level level, int x, int z, BaseBiome biome, Long seed) {
|
||||
level.regenerateChunk(x, z);
|
||||
@ -263,8 +253,18 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadChunk(Level level, int x, int z, boolean generate) {
|
||||
return level.loadChunk(x, z, generate);
|
||||
public BaseFullChunk loadChunk(Level level, int x, int z, boolean generate) {
|
||||
return level.getChunk(x, z, generate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseFullChunk getSections(BaseFullChunk baseFullChunk) {
|
||||
return baseFullChunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseFullChunk getCachedChunk(Level level, int cx, int cz) {
|
||||
return level.getProvider().getChunk(cx, cz);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -273,6 +273,11 @@ public class NukkitQueue extends NMSMappedFaweQueue<Level, BaseFullChunk, BaseFu
|
||||
return chunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBiome(BaseFullChunk baseFullChunk, int x, int z) {
|
||||
return baseFullChunk.getBiomeId(x & 15, z & 15);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseFullChunk getCachedSection(BaseFullChunk baseFullChunk, int cy) {
|
||||
return baseFullChunk;
|
||||
|
@ -72,6 +72,7 @@ shadowJar {
|
||||
relocate 'org.yaml.snakeyaml', 'com.boydti.fawe.yaml'
|
||||
dependencies {
|
||||
include(dependency('com.github.luben:zstd-jni:1.1.1'))
|
||||
include(dependency('co.aikar:fastutil-lite:1.0'))
|
||||
include(dependency(':core'))
|
||||
include(dependency('org.yaml:snakeyaml:1.16'))
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.boydti.fawe.sponge;
|
||||
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import org.spongepowered.api.Sponge;
|
||||
import org.spongepowered.api.scheduler.Task;
|
||||
@ -16,7 +16,7 @@ public class SpongeTaskMan extends TaskManager {
|
||||
|
||||
private final AtomicInteger i = new AtomicInteger();
|
||||
|
||||
private final HashMap<Integer, Task> tasks = new HashMap<>();
|
||||
private final ConcurrentHashMap<Integer, Task> tasks = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
public int repeat(Runnable runnable, int interval) {
|
||||
|
Loading…
Reference in New Issue
Block a user