Fix removal of light sources
This commit is contained in:
parent
951a6a88b9
commit
5b0ce58f6b
17473
blocks.json
17473
blocks.json
File diff suppressed because it is too large
Load Diff
@ -31,19 +31,19 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_All(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_All(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_All copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_All(getParent(), getX(), getZ(), ids, count, air, relight, heightMap);
|
||||
copy = new BukkitChunk_All(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_All(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone());
|
||||
copy = new BukkitChunk_All(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -130,7 +130,6 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
try {
|
||||
// Efficiently merge sections
|
||||
int changes = getCount(layer);
|
||||
int lighting = getRelight(layer);
|
||||
if (changes == 0) {
|
||||
continue;
|
||||
}
|
||||
@ -141,7 +140,7 @@ public class BukkitChunk_All extends CharFaweChunk<Chunk, BukkitQueue_All> {
|
||||
final byte[] cacheX = FaweCache.CACHE_X[layer];
|
||||
final short[] cacheY = FaweCache.CACHE_Y[layer];
|
||||
final byte[] cacheZ = FaweCache.CACHE_Z[layer];
|
||||
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))) && getRelight(layer) == 0);
|
||||
boolean checkTime = !((getAir(layer) == 4096 || (getCount(layer) == 4096 && getAir(layer) == 0) || (getCount(layer) == getAir(layer))));
|
||||
if (!checkTime) {
|
||||
ArrayList<Thread> threads = new ArrayList<Thread>();
|
||||
for (int k = 0; k < 16; k++) {
|
||||
|
@ -76,7 +76,6 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
public static void checkVersion(String supported) {
|
||||
String version = Bukkit.getServer().getClass().getPackage().getName();
|
||||
if (!version.contains(supported)) {
|
||||
Fawe.debug("This version of FAWE is for: " + supported);
|
||||
throw new IllegalStateException("Unsupported version: " + version + " (supports: " + supported + ")");
|
||||
}
|
||||
}
|
||||
@ -120,17 +119,17 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
|
||||
return world;
|
||||
}
|
||||
|
||||
public void setupAdapter(BukkitImplAdapter adapter) {
|
||||
public static void setupAdapter(BukkitImplAdapter adapter) {
|
||||
try {
|
||||
WorldEditPlugin instance = (WorldEditPlugin) Bukkit.getPluginManager().getPlugin("WorldEdit");
|
||||
Field fieldAdapter = WorldEditPlugin.class.getDeclaredField("bukkitAdapter");
|
||||
fieldAdapter.setAccessible(true);
|
||||
if ((this.adapter = adapter) != null) {
|
||||
if ((BukkitQueue_0.adapter = adapter) != null) {
|
||||
fieldAdapter.set(instance, adapter);
|
||||
} else {
|
||||
this.adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||
BukkitQueue_0.adapter = (BukkitImplAdapter) fieldAdapter.get(instance);
|
||||
}
|
||||
for (Method method : this.adapter.getClass().getDeclaredMethods()) {
|
||||
for (Method method : BukkitQueue_0.adapter.getClass().getDeclaredMethods()) {
|
||||
switch (method.getName()) {
|
||||
case "toNative":
|
||||
methodToNative = method;
|
||||
|
@ -59,19 +59,19 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_10(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_1_10(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_10 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), ids, count, air, relight, heightMap);
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone());
|
||||
copy = new BukkitChunk_1_10(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -181,6 +181,8 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
try {
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_10_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
nmsChunk.f(true); // Set Modified
|
||||
@ -349,8 +351,10 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int by = j << 4;
|
||||
DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
IBlockData existing;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
short[][] i1 = FaweCache.CACHE_J[y];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
@ -359,22 +363,32 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
char combinedId = array[i2[x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_10.air) {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_10.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_10.air);
|
||||
continue;
|
||||
default:
|
||||
nonEmptyBlockCount++;
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_10.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, nonEmptyBlockCount, section);
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
@ -395,8 +409,6 @@ public class BukkitChunk_1_10 extends CharFaweChunk<Chunk, BukkitQueue_1_10> {
|
||||
}
|
||||
// Set tiles
|
||||
Map<BytePair, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
|
@ -41,17 +41,49 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Method getEntitySlices;
|
||||
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_10_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_10(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_10(final String world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,34 +100,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
checkVersion("v1_10_R1");
|
||||
if (air == null) {
|
||||
try {
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_10_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_10.FaweAdapter_1_10());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, ExecutorCompletionService pool, long time) {
|
||||
return super.next(amount, pool, time);
|
||||
@ -357,19 +361,18 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||
|
@ -62,19 +62,19 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_11(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_1_11(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_11 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), ids, count, air, relight, heightMap);
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone());
|
||||
copy = new BukkitChunk_1_11(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -184,13 +184,14 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
try {
|
||||
final Chunk chunk = this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_11_R1.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
nmsChunk.f(true); // Set Modified
|
||||
nmsChunk.mustSave = true;
|
||||
net.minecraft.server.v1_11_R1.World nmsWorld = nmsChunk.world;
|
||||
ChunkSection[] sections = nmsChunk.getSections();
|
||||
Class<? extends net.minecraft.server.v1_11_R1.Chunk> clazzChunk = nmsChunk.getClass();
|
||||
final Collection<Entity>[] entities = (Collection<Entity>[]) getParent().getEntitySlices.invoke(nmsChunk);
|
||||
Map<BlockPosition, TileEntity> tiles = nmsChunk.getTileEntities();
|
||||
// Set heightmap
|
||||
@ -363,8 +364,10 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int by = j << 4;
|
||||
DataPaletteBlock nibble = section.getBlocks();
|
||||
int nonEmptyBlockCount = 0;
|
||||
IBlockData existing;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
short[][] i1 = FaweCache.CACHE_J[y];
|
||||
for (int z = 0; z < 16; z++) {
|
||||
@ -373,22 +376,32 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
char combinedId = array[i2[x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
if (existing != com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.air) {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
nibble.setBlock(x, y, z, com.boydti.fawe.bukkit.v1_11.BukkitQueue_1_11.air);
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_11.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_11.air);
|
||||
continue;
|
||||
default:
|
||||
nonEmptyBlockCount++;
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_11.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, getParent().IBD_CACHE[(int) combinedId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, nonEmptyBlockCount, section);
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
@ -409,9 +422,6 @@ public class BukkitChunk_1_11 extends CharFaweChunk<Chunk, com.boydti.fawe.bukki
|
||||
}
|
||||
// Set tiles
|
||||
Map<BytePair, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
BytePair pair = entry.getKey();
|
||||
|
@ -41,17 +41,51 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Method getEntitySlices;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
|
||||
public static final IBlockData[] IBD_CACHE = new IBlockData[Character.MAX_VALUE];
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_11_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_11.FaweAdapter_1_11());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_11(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_11(final String world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,34 +102,6 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
}
|
||||
|
||||
private void init() {
|
||||
checkVersion("v1_11_R1");
|
||||
if (air == null) {
|
||||
try {
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
getEntitySlices = net.minecraft.server.v1_11_R1.Chunk.class.getDeclaredMethod("getEntitySlices");
|
||||
getEntitySlices.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new com.boydti.fawe.bukkit.v1_11.FaweAdapter_1_11());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
for (int i = 0; i < Character.MAX_VALUE; i++) {
|
||||
try {
|
||||
IBD_CACHE[i] = Block.getById(i >> 4).fromLegacyData(i & 0xF);
|
||||
} catch (Throwable ignore) {}
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean next(int amount, ExecutorCompletionService pool, long time) {
|
||||
return super.next(amount, pool, time);
|
||||
@ -357,19 +363,17 @@ public class BukkitQueue_1_11 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||
|
@ -52,8 +52,8 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
this.datas = new NibbleArray[16];
|
||||
}
|
||||
|
||||
public BukkitChunk_1_7(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap, byte[][] byteIds, NibbleArray[] datas) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_1_7(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap, byte[][] byteIds, NibbleArray[] datas) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
this.byteIds = byteIds;
|
||||
this.datas = datas;
|
||||
}
|
||||
@ -62,11 +62,11 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_7 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), ids, count, air, relight, heightMap, byteIds, datas);
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), ids, count, air, heightMap, byteIds, datas);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone(), (byte[][]) MainUtil.copyNd(byteIds), datas.clone());
|
||||
copy = new BukkitChunk_1_7(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone(), (byte[][]) MainUtil.copyNd(byteIds), datas.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -122,7 +122,7 @@ public class BukkitChunk_1_7 extends CharFaweChunk<Chunk, BukkitQueue17> {
|
||||
case 62:
|
||||
case 50:
|
||||
case 10:
|
||||
this.relight[i]++;
|
||||
getParent().getRelighter().addLightUpdate((getX() << 4) + x, y, (getZ() << 4) + z);
|
||||
default:
|
||||
vs2[j] = (char) ((id << 4) + data);
|
||||
vs[j] = (byte) id;
|
||||
|
@ -38,29 +38,31 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
|
||||
protected static Field fieldData;
|
||||
protected static Field fieldIds;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldData = ChunkSection.class.getDeclaredField("blockData");
|
||||
fieldData.setAccessible(true);
|
||||
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldIds.setAccessible(true);
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue17(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue17(final String world) {
|
||||
super(world);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
checkVersion("v1_7_R4");
|
||||
if (fieldData == null) {
|
||||
try {
|
||||
fieldData = ChunkSection.class.getDeclaredField("blockData");
|
||||
fieldData.setAccessible(true);
|
||||
fieldIds = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldIds.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@ -229,16 +231,13 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
|
@ -46,19 +46,19 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_8(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_1_8(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_8 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), ids, count, air, relight, heightMap);
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone());
|
||||
copy = new BukkitChunk_1_8(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -80,6 +80,8 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
@Override
|
||||
public FaweChunk call() {
|
||||
CraftChunk chunk = (CraftChunk) this.getChunk();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
net.minecraft.server.v1_8_R3.Chunk nmsChunk = chunk.getHandle();
|
||||
nmsChunk.f(true); // Modified
|
||||
nmsChunk.mustSave = true;
|
||||
@ -233,26 +235,43 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
sections[j] = section;
|
||||
continue;
|
||||
}
|
||||
int by = j << 4;
|
||||
char[] currentArray = section.getIdArray();
|
||||
int solid = 0;
|
||||
int existingId;
|
||||
for (int k = 0; k < newArray.length; k++) {
|
||||
char n = newArray[k];
|
||||
switch (n) {
|
||||
case 0:
|
||||
continue;
|
||||
case 1:
|
||||
if (currentArray[k] > 1) {
|
||||
solid++;
|
||||
existingId = currentArray[k];
|
||||
if (existingId > 1) {
|
||||
if (FaweCache.hasLight(existingId)) {
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
getParent().getRelighter().addLightUpdate(bx + x, y, bz + z);
|
||||
}
|
||||
solid--;
|
||||
currentArray[k] = 0;
|
||||
}
|
||||
continue;
|
||||
default:
|
||||
solid++;
|
||||
existingId = currentArray[k];
|
||||
if (existingId <= 1) {
|
||||
solid++;
|
||||
} else if (FaweCache.hasLight(existingId)) {
|
||||
int x = FaweCache.CACHE_X[j][k];
|
||||
int y = FaweCache.CACHE_Y[j][k];
|
||||
int z = FaweCache.CACHE_Z[j][k];
|
||||
getParent().getRelighter().addLightUpdate(bx + x, y, bz + z);
|
||||
}
|
||||
currentArray[k] = n;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, solid, section);
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + solid, section);
|
||||
}
|
||||
|
||||
// Set biomes
|
||||
@ -274,9 +293,6 @@ public class BukkitChunk_1_8 extends CharFaweChunk<Chunk, BukkitQueue18R3> {
|
||||
}
|
||||
// Set tiles
|
||||
Map<BytePair, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
BytePair pair = entry.getKey();
|
||||
|
@ -1,6 +1,5 @@
|
||||
package com.boydti.fawe.bukkit.v1_8;
|
||||
|
||||
import com.boydti.fawe.Fawe;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||
import com.boydti.fawe.example.CharFaweChunk;
|
||||
@ -13,7 +12,6 @@ import com.boydti.fawe.util.TaskManager;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
import com.sk89q.jnbt.StringTag;
|
||||
import com.sk89q.jnbt.Tag;
|
||||
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Arrays;
|
||||
@ -39,26 +37,35 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
|
||||
public static Field isDirty;
|
||||
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
protected static Field fieldChunkMap;
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldChunkMap = PlayerChunkMap.class.getDeclaredField("d");
|
||||
isDirty = ChunkSection.class.getDeclaredField("isDirty");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldChunkMap.setAccessible(true);
|
||||
isDirty.setAccessible(true);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue18R3(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
checkVersion("v1_8_R3");
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue18R3(final String world) {
|
||||
super(world);
|
||||
checkVersion("v1_8_R3");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setupAdapter(BukkitImplAdapter adapter) {
|
||||
if (this.adapter == null) {
|
||||
try {
|
||||
isDirty = ChunkSection.class.getDeclaredField("isDirty");
|
||||
isDirty.setAccessible(true);
|
||||
Fawe.debug("isDirty found");
|
||||
} catch (Throwable e) {}
|
||||
}
|
||||
super.setupAdapter(adapter);
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@ -225,15 +232,14 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshChunk(FaweChunk fc) {
|
||||
BukkitChunk_1_8 fs = (BukkitChunk_1_8) fc;
|
||||
@ -251,8 +257,7 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkS
|
||||
if (!chunkMap.isChunkInUse(x, z)) {
|
||||
return;
|
||||
}
|
||||
Field fieldChunkMap = chunkMap.getClass().getDeclaredField("d");
|
||||
fieldChunkMap.setAccessible(true);
|
||||
|
||||
LongHashMap<Object> map = (LongHashMap<Object>) fieldChunkMap.get(chunkMap);
|
||||
long pair = (long) x + 2147483647L | (long) z + 2147483647L << 32;
|
||||
Object playerChunk = map.getEntry(pair);
|
||||
|
@ -28,7 +28,6 @@ import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_9_R2.Block;
|
||||
import net.minecraft.server.v1_9_R2.BlockPosition;
|
||||
import net.minecraft.server.v1_9_R2.Blocks;
|
||||
import net.minecraft.server.v1_9_R2.ChunkSection;
|
||||
import net.minecraft.server.v1_9_R2.DataBits;
|
||||
import net.minecraft.server.v1_9_R2.DataPalette;
|
||||
@ -61,19 +60,19 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
super(parent, x, z);
|
||||
}
|
||||
|
||||
public BukkitChunk_1_9(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, relight, heightMap);
|
||||
public BukkitChunk_1_9(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z, ids, count, air, heightMap);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharFaweChunk copy(boolean shallow) {
|
||||
BukkitChunk_1_9 copy;
|
||||
if (shallow) {
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), ids, count, air, relight, heightMap);
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), ids, count, air, heightMap);
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
} else {
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), relight.clone(), heightMap.clone());
|
||||
copy = new BukkitChunk_1_9(getParent(), getX(), getZ(), (char[][]) MainUtil.copyNd(ids), count.clone(), air.clone(), heightMap.clone());
|
||||
copy.biomes = biomes;
|
||||
copy.chunk = chunk;
|
||||
copy.biomes = biomes.clone();
|
||||
@ -182,6 +181,8 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
public FaweChunk call() {
|
||||
final Chunk chunk = (Chunk) this.getChunk();
|
||||
final World world = chunk.getWorld();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
try {
|
||||
final boolean flag = world.getEnvironment() == World.Environment.NORMAL;
|
||||
net.minecraft.server.v1_9_R2.Chunk nmsChunk = ((CraftChunk) chunk).getHandle();
|
||||
@ -361,28 +362,40 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
fieldPalette.setAccessible(true);
|
||||
DataPalette palette = (DataPalette) fieldPalette.get(nibble);
|
||||
int nonEmptyBlockCount = 0;
|
||||
IBlockData existing;
|
||||
int by = j << 4;
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
char combinedId = array[FaweCache.CACHE_J[y][z][x]];
|
||||
switch (combinedId) {
|
||||
case 0:
|
||||
IBlockData existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_9_R1.air) {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
continue;
|
||||
case 1:
|
||||
nibble.setBlock(x, y, z, Blocks.AIR.getBlockData());
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_9_R1.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
nonEmptyBlockCount--;
|
||||
}
|
||||
nibble.setBlock(x, y, z, BukkitQueue_1_9_R1.air);
|
||||
continue;
|
||||
default:
|
||||
nonEmptyBlockCount++;
|
||||
existing = nibble.a(x, y, z);
|
||||
if (existing != BukkitQueue_1_9_R1.air) {
|
||||
if (existing.d() > 0) {
|
||||
getParent().getRelighter().addLightUpdate(bx + x, by + y, bz + z);
|
||||
}
|
||||
} else {
|
||||
nonEmptyBlockCount++;
|
||||
}
|
||||
nibble.setBlock(x, y, z, Block.getById(combinedId >> 4).fromLegacyData(combinedId & 0xF));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
getParent().setCount(0, nonEmptyBlockCount, section);
|
||||
getParent().setCount(0, getParent().getNonEmptyBlockCount(section) + nonEmptyBlockCount, section);
|
||||
}
|
||||
// Set biomes
|
||||
int[][] biomes = this.biomes;
|
||||
@ -403,9 +416,6 @@ public class BukkitChunk_1_9 extends CharFaweChunk<Chunk, BukkitQueue_1_9_R1> {
|
||||
}
|
||||
// Set tiles
|
||||
Map<BytePair, CompoundTag> tilesToSpawn = this.getTiles();
|
||||
int bx = this.getX() << 4;
|
||||
int bz = this.getZ() << 4;
|
||||
|
||||
for (Map.Entry<BytePair, CompoundTag> entry : tilesToSpawn.entrySet()) {
|
||||
CompoundTag nativeTag = entry.getValue();
|
||||
BytePair pair = entry.getKey();
|
||||
|
@ -23,7 +23,32 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.server.v1_9_R2.*;
|
||||
import net.minecraft.server.v1_9_R2.Block;
|
||||
import net.minecraft.server.v1_9_R2.BlockPosition;
|
||||
import net.minecraft.server.v1_9_R2.ChunkSection;
|
||||
import net.minecraft.server.v1_9_R2.DataBits;
|
||||
import net.minecraft.server.v1_9_R2.DataPaletteBlock;
|
||||
import net.minecraft.server.v1_9_R2.Entity;
|
||||
import net.minecraft.server.v1_9_R2.EntityPlayer;
|
||||
import net.minecraft.server.v1_9_R2.EntityTracker;
|
||||
import net.minecraft.server.v1_9_R2.EntityTypes;
|
||||
import net.minecraft.server.v1_9_R2.EnumDifficulty;
|
||||
import net.minecraft.server.v1_9_R2.EnumSkyBlock;
|
||||
import net.minecraft.server.v1_9_R2.IBlockData;
|
||||
import net.minecraft.server.v1_9_R2.IDataManager;
|
||||
import net.minecraft.server.v1_9_R2.MinecraftServer;
|
||||
import net.minecraft.server.v1_9_R2.NBTTagCompound;
|
||||
import net.minecraft.server.v1_9_R2.NibbleArray;
|
||||
import net.minecraft.server.v1_9_R2.PacketPlayOutMapChunk;
|
||||
import net.minecraft.server.v1_9_R2.PlayerChunk;
|
||||
import net.minecraft.server.v1_9_R2.PlayerChunkMap;
|
||||
import net.minecraft.server.v1_9_R2.ServerNBTManager;
|
||||
import net.minecraft.server.v1_9_R2.TileEntity;
|
||||
import net.minecraft.server.v1_9_R2.WorldData;
|
||||
import net.minecraft.server.v1_9_R2.WorldManager;
|
||||
import net.minecraft.server.v1_9_R2.WorldServer;
|
||||
import net.minecraft.server.v1_9_R2.WorldSettings;
|
||||
import net.minecraft.server.v1_9_R2.WorldType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
@ -39,35 +64,41 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
|
||||
protected static IBlockData air;
|
||||
protected static Field fieldBits;
|
||||
protected static Field fieldTickingBlockCount;
|
||||
protected static Field fieldNonEmptyBlockCount;
|
||||
protected static Field fieldSection;
|
||||
|
||||
static {
|
||||
try {
|
||||
fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldTickingBlockCount = ChunkSection.class.getDeclaredField("tickingBlockCount");
|
||||
fieldNonEmptyBlockCount = ChunkSection.class.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new FaweAdapter_1_9());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public BukkitQueue_1_9_R1(final com.sk89q.worldedit.world.World world) {
|
||||
super(world);
|
||||
init();
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
public BukkitQueue_1_9_R1(final String world) {
|
||||
super(world);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
checkVersion("v1_9_R2");
|
||||
if (air == null) {
|
||||
try {
|
||||
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
|
||||
fieldAir.setAccessible(true);
|
||||
air = (IBlockData) fieldAir.get(null);
|
||||
fieldBits = DataPaletteBlock.class.getDeclaredField("b");
|
||||
fieldBits.setAccessible(true);
|
||||
if (adapter == null) {
|
||||
setupAdapter(new FaweAdapter_1_9());
|
||||
Fawe.debug("Using adapter: " + adapter);
|
||||
Fawe.debug("=========================================");
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
getImpWorld();
|
||||
}
|
||||
|
||||
@ -310,19 +341,17 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Chu
|
||||
}
|
||||
|
||||
public void setCount(int tickingBlockCount, int nonEmptyBlockCount, ChunkSection section) throws NoSuchFieldException, IllegalAccessException {
|
||||
Class<? extends ChunkSection> clazz = section.getClass();
|
||||
Field fieldTickingBlockCount = clazz.getDeclaredField("tickingBlockCount");
|
||||
Field fieldNonEmptyBlockCount = clazz.getDeclaredField("nonEmptyBlockCount");
|
||||
fieldTickingBlockCount.setAccessible(true);
|
||||
fieldNonEmptyBlockCount.setAccessible(true);
|
||||
fieldTickingBlockCount.set(section, tickingBlockCount);
|
||||
fieldNonEmptyBlockCount.set(section, nonEmptyBlockCount);
|
||||
}
|
||||
|
||||
public int getNonEmptyBlockCount(ChunkSection section) throws IllegalAccessException {
|
||||
return (int) fieldNonEmptyBlockCount.get(section);
|
||||
}
|
||||
|
||||
public void setPalette(ChunkSection section, DataPaletteBlock palette) throws NoSuchFieldException, IllegalAccessException {
|
||||
Field fieldSection = ChunkSection.class.getDeclaredField("blockIds");
|
||||
fieldSection.setAccessible(true);
|
||||
fieldSection.set(section, palette);
|
||||
Arrays.fill(section.getEmittedLightArray().asBytes(), (byte) 0);
|
||||
}
|
||||
|
||||
public ChunkSection newChunkSection(int y2, boolean flag, char[] array) {
|
||||
|
@ -285,7 +285,6 @@ public class Fawe {
|
||||
}
|
||||
|
||||
public void setupConfigs() {
|
||||
|
||||
// Setting up config.yml
|
||||
File file = new File(this.IMP.getDirectory(), "config.yml");
|
||||
Settings.PLATFORM = IMP.getPlatform().replace("\"", "");
|
||||
|
@ -7,7 +7,6 @@ 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.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
@ -19,7 +18,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
public final char[][] ids;
|
||||
public final short[] count;
|
||||
public final short[] air;
|
||||
public final short[] relight;
|
||||
public final byte[] heightMap;
|
||||
|
||||
public int[][] biomes;
|
||||
@ -29,12 +27,11 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
|
||||
public T chunk;
|
||||
|
||||
public CharFaweChunk(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, short[] relight, byte[] heightMap) {
|
||||
public CharFaweChunk(FaweQueue parent, int x, int z, char[][] ids, short[] count, short[] air, byte[] heightMap) {
|
||||
super(parent, x, z);
|
||||
this.ids = ids;
|
||||
this.count = count;
|
||||
this.air = air;
|
||||
this.relight = relight;
|
||||
this.heightMap = heightMap;
|
||||
}
|
||||
|
||||
@ -50,7 +47,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
this.ids = new char[HEIGHT >> 4][];
|
||||
this.count = new short[HEIGHT >> 4];
|
||||
this.air = new short[HEIGHT >> 4];
|
||||
this.relight = new short[HEIGHT >> 4];
|
||||
this.heightMap = new byte[256];
|
||||
}
|
||||
|
||||
@ -92,15 +88,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
this.count[i] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of block changes in a specified section
|
||||
* @param i
|
||||
* @return
|
||||
*/
|
||||
public int getRelight(final int i) {
|
||||
return this.relight[i];
|
||||
}
|
||||
|
||||
public int getTotalCount() {
|
||||
int total = 0;
|
||||
for (int i = 0; i < count.length; i++) {
|
||||
@ -109,19 +96,6 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
return total;
|
||||
}
|
||||
|
||||
public int getTotalRelight() {
|
||||
if ((this.getTotalCount() == 0) && (this.biomes == null)) {
|
||||
Arrays.fill(this.count, (short) 1);
|
||||
Arrays.fill(this.relight, Short.MAX_VALUE);
|
||||
return Short.MAX_VALUE;
|
||||
}
|
||||
int total = 0;
|
||||
for (int i = 0; i < relight.length; i++) {
|
||||
total += this.relight[i];
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBitMask() {
|
||||
int bitMask = 0;
|
||||
@ -245,7 +219,7 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 62:
|
||||
case 50:
|
||||
case 10:
|
||||
this.relight[i]++;
|
||||
getParent().getRelighter().addLightUpdate((getX() << 4) + x, y, (getZ() << 4) + z);
|
||||
default:
|
||||
vs[j] = (char) (id << 4);
|
||||
heightMap[z << 4 | x] = (byte) y;
|
||||
@ -280,7 +254,7 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 138:
|
||||
case 169:
|
||||
case 213:
|
||||
this.relight[i]++;
|
||||
getParent().getRelighter().addLightUpdate((getX() << 4) + x, y, (getZ() << 4) + z);
|
||||
case 2:
|
||||
case 4:
|
||||
case 13:
|
||||
@ -341,7 +315,7 @@ public abstract class CharFaweChunk<T, V extends FaweQueue> extends FaweChunk<T>
|
||||
case 62:
|
||||
case 50:
|
||||
case 10:
|
||||
this.relight[i]++;
|
||||
getParent().getRelighter().addLightUpdate((getX() << 4) + x, y, (getZ() << 4) + z);
|
||||
case 54:
|
||||
case 146:
|
||||
case 61:
|
||||
|
@ -40,19 +40,22 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
@Override
|
||||
public void runTasks() {
|
||||
super.runTasks();
|
||||
final NMSRelighter tmp = relighter;
|
||||
relighter = null;
|
||||
if (tmp != null) {
|
||||
if (!relighter.isEmpty()) {
|
||||
TaskManager.IMP.taskNowAsync(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tmp.fixLightingSafe(hasSky());
|
||||
relighter.fixLightingSafe(hasSky());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private NMSRelighter relighter;
|
||||
private final Relighter relighter = Settings.LIGHTING.MODE > 0 ? new NMSRelighter(this) : NullRelighter.INSTANCE;
|
||||
|
||||
@Override
|
||||
public Relighter getRelighter() {
|
||||
return relighter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void end(FaweChunk chunk) {
|
||||
@ -61,13 +64,8 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
sendChunk(chunk);
|
||||
return;
|
||||
}
|
||||
NMSRelighter tmp = relighter;
|
||||
if (tmp == null) {
|
||||
relighter = tmp = new NMSRelighter(this);
|
||||
}
|
||||
|
||||
if (Settings.LIGHTING.MODE == 2) {
|
||||
tmp.addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||
relighter.addChunk(chunk.getX(), chunk.getZ(), null, chunk.getBitMask());
|
||||
return;
|
||||
}
|
||||
CharFaweChunk cfc = (CharFaweChunk) chunk;
|
||||
@ -75,13 +73,13 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
|
||||
boolean[] fix = new boolean[(maxY + 1) >> 4];
|
||||
boolean sky = hasSky();
|
||||
for (int i = 0; i < cfc.ids.length; i++) {
|
||||
if ((sky && ((cfc.getAir(i) & 4095) != 0 || (cfc.getCount(i) & 4095) != 0)) || cfc.getRelight(i) != 0) {
|
||||
if ((sky && ((cfc.getAir(i) & 4095) != 0 || (cfc.getCount(i) & 4095) != 0))) {
|
||||
relight = true;
|
||||
fix[i] = true;
|
||||
}
|
||||
}
|
||||
if (relight) {
|
||||
tmp.addChunk(chunk.getX(), chunk.getZ(), fix, chunk.getBitMask());
|
||||
relighter.addChunk(chunk.getX(), chunk.getZ(), fix, chunk.getBitMask());
|
||||
} else {
|
||||
sendChunk(chunk);
|
||||
}
|
||||
|
@ -3,24 +3,47 @@ package com.boydti.fawe.example;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
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 java.util.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class NMSRelighter {
|
||||
public class NMSRelighter implements Relighter{
|
||||
private final NMSMappedFaweQueue queue;
|
||||
|
||||
private final Map<Long, RelightSkyEntry> skyToRelight;
|
||||
private final Map<Long, RelightBlockEntry> blocksToRelight;
|
||||
private final Map<Long, Map<Short, Object>> lightQueue;
|
||||
private final Object present = new Object();
|
||||
private final Set<Long> chunksToSend;
|
||||
|
||||
private final int maxY;
|
||||
private volatile boolean relighting = false;
|
||||
|
||||
public final IntegerTrio mutableBlockPos = new IntegerTrio();
|
||||
|
||||
private static final int DISPATCH_SIZE = 64;
|
||||
|
||||
public NMSRelighter(NMSMappedFaweQueue queue) {
|
||||
this.queue = queue;
|
||||
skyToRelight = new ConcurrentHashMap<>();
|
||||
blocksToRelight = new ConcurrentHashMap<>();
|
||||
this.maxY = queue.getWEWorld().getMaxY();
|
||||
this.skyToRelight = new ConcurrentHashMap<>();
|
||||
this.lightQueue = new ConcurrentHashMap<>();
|
||||
chunksToSend = new LinkedHashSet<>();
|
||||
this.maxY = queue.getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return skyToRelight.isEmpty() && lightQueue.isEmpty();
|
||||
}
|
||||
|
||||
public boolean addChunk(int cx, int cz, boolean[] fix, int bitmask) {
|
||||
@ -47,38 +70,135 @@ public class NMSRelighter {
|
||||
}
|
||||
}
|
||||
|
||||
public void addBlock(int x, int y, int z) {
|
||||
if (y < 1) {
|
||||
public void updateBlockLight(Map<Long, Map<Short, Object>> map) {
|
||||
int size = map.size();
|
||||
if (size == 0) {
|
||||
return;
|
||||
}
|
||||
int cx = x >> 4;
|
||||
int cz = z >> 4;
|
||||
long pair = MathMan.pairInt(cx, cz);
|
||||
RelightBlockEntry current = blocksToRelight.get(pair);
|
||||
if (current == null) {
|
||||
current = new RelightBlockEntry(pair);
|
||||
blocksToRelight.put(pair, current);
|
||||
}
|
||||
current.addBlock(x, y, z);
|
||||
}
|
||||
Queue<IntegerTrio> lightPropagationQueue = new ArrayDeque<>();
|
||||
Queue<Object[]> lightRemovalQueue = new ArrayDeque<>();
|
||||
Map<IntegerTrio, Object> visited = new HashMap<>();
|
||||
Map<IntegerTrio, Object> removalVisited = new HashMap<>();
|
||||
|
||||
public void smoothBlockLight(int emit, int x, int y, int z, int rx, int ry, int rz) {
|
||||
int opacity = queue.getOpacity(rx, ry, rz);
|
||||
if (opacity >= emit) {
|
||||
return;
|
||||
Iterator<Map.Entry<Long, Map<Short, Object>>> iter = map.entrySet().iterator();
|
||||
while (iter.hasNext() && size-- > 0) {
|
||||
Map.Entry<Long, Map<Short, Object>> entry = iter.next();
|
||||
iter.remove();
|
||||
long index = entry.getKey();
|
||||
Map<Short, 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()) {
|
||||
int hi = (byte) (blockHash >>> 8);
|
||||
int lo = (byte) blockHash;
|
||||
int y = lo & 0xFF;
|
||||
int x = (hi & 0xF) + bx;
|
||||
int z = ((hi >> 4) & 0xF) + bz;
|
||||
int lcx = x & 0xF;
|
||||
int lcz = z & 0xF;
|
||||
int oldLevel = queue.getEmmittedLight(x, y, z);
|
||||
int newLevel = queue.getBrightness(x, y, z);
|
||||
if (oldLevel != newLevel) {
|
||||
queue.setBlockLight(x, y, z, newLevel);
|
||||
IntegerTrio node = new IntegerTrio(x, y, z);
|
||||
if (newLevel < oldLevel) {
|
||||
removalVisited.put(node, present);
|
||||
lightRemovalQueue.add(new Object[] { node, oldLevel });
|
||||
} else {
|
||||
visited.put(node, present);
|
||||
lightPropagationQueue.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int emitAdjacent = queue.getEmmittedLight(rx, ry, rz);
|
||||
if (emit - emitAdjacent > 1) {
|
||||
queue.setBlockLight(rx, ry, rz, emit - 1);
|
||||
addBlock(rx, ry, rz);
|
||||
|
||||
while (!lightRemovalQueue.isEmpty()) {
|
||||
Object[] val = lightRemovalQueue.poll();
|
||||
IntegerTrio node = (IntegerTrio) val[0];
|
||||
int lightLevel = (int) val[1];
|
||||
|
||||
this.computeRemoveBlockLight(node.x - 1, node.y, node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
this.computeRemoveBlockLight(node.x + 1, node.y, node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
if (node.y > 0) {
|
||||
this.computeRemoveBlockLight(node.x, node.y - 1, node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
}
|
||||
if (node.y < 255) {
|
||||
this.computeRemoveBlockLight(node.x, node.y + 1, node.z, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
}
|
||||
this.computeRemoveBlockLight(node.x, node.y, node.z - 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
this.computeRemoveBlockLight(node.x, node.y, node.z + 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
||||
}
|
||||
|
||||
while (!lightPropagationQueue.isEmpty()) {
|
||||
IntegerTrio node = lightPropagationQueue.poll();
|
||||
int lightLevel = queue.getEmmittedLight(node.x, node.y, node.z);
|
||||
if (lightLevel > 1) {
|
||||
this.computeSpreadBlockLight(node.x - 1, node.y, node.z, lightLevel, lightPropagationQueue, visited);
|
||||
this.computeSpreadBlockLight(node.x + 1, node.y, node.z, lightLevel, lightPropagationQueue, visited);
|
||||
if (node.y > 0) {
|
||||
this.computeSpreadBlockLight(node.x, node.y - 1, node.z, lightLevel, lightPropagationQueue, visited);
|
||||
}
|
||||
if (node.y < 255) {
|
||||
this.computeSpreadBlockLight(node.x, node.y + 1, node.z, lightLevel, lightPropagationQueue, visited);
|
||||
}
|
||||
this.computeSpreadBlockLight(node.x, node.y, node.z - 1, lightLevel, lightPropagationQueue, visited);
|
||||
this.computeSpreadBlockLight(node.x, node.y, node.z + 1, lightLevel, lightPropagationQueue, visited);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void fixLightingSafe(boolean sky) {
|
||||
if (relighting) {
|
||||
return;
|
||||
private void computeRemoveBlockLight(int x, int y, int z, int currentLight, Queue<Object[]> queue, Queue<IntegerTrio> spreadQueue, Map<IntegerTrio, Object> visited,
|
||||
Map<IntegerTrio, Object> spreadVisited) {
|
||||
int current = this.queue.getEmmittedLight(x, y, z);
|
||||
if (current != 0 && current < currentLight) {
|
||||
this.queue.setBlockLight(x, y, z, 0);
|
||||
if (current > 1) {
|
||||
if (!visited.containsKey(mutableBlockPos)) {
|
||||
IntegerTrio index = new IntegerTrio(x, y, z);
|
||||
visited.put(index, present);
|
||||
queue.add(new Object[] { index, current });
|
||||
}
|
||||
}
|
||||
} else if (current >= currentLight) {
|
||||
mutableBlockPos.set(x, y, z);
|
||||
if (!spreadVisited.containsKey(mutableBlockPos)) {
|
||||
IntegerTrio index = new IntegerTrio(x, y, z);
|
||||
spreadVisited.put(index, present);
|
||||
spreadQueue.add(index);
|
||||
}
|
||||
}
|
||||
relighting = true;
|
||||
}
|
||||
|
||||
private void computeSpreadBlockLight(int x, int y, int z, int currentLight, Queue<IntegerTrio> queue, Map<IntegerTrio, Object> visited) {
|
||||
currentLight = currentLight - Math.max(1, this.queue.getOpacity(x, y, z));
|
||||
if (currentLight > 0) {
|
||||
int current = this.queue.getEmmittedLight(x, y, z);
|
||||
if (current < currentLight) {
|
||||
this.queue.setBlockLight(x, y, z, currentLight);
|
||||
mutableBlockPos.set(x, y, z);
|
||||
if (!visited.containsKey(mutableBlockPos)) {
|
||||
visited.put(new IntegerTrio(x, y, z), present);
|
||||
if (currentLight > 1) {
|
||||
queue.add(new IntegerTrio(x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
if (currentMap == null) {
|
||||
currentMap = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
this.lightQueue.put(index, currentMap);
|
||||
}
|
||||
currentMap.put(MathMan.tripleBlockCoord(x, y, z), present);
|
||||
}
|
||||
|
||||
public synchronized void fixLightingSafe(boolean sky) {
|
||||
try {
|
||||
if (sky) {
|
||||
fixSkyLighting();
|
||||
@ -88,46 +208,20 @@ public class NMSRelighter {
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
relighting = false;
|
||||
}
|
||||
|
||||
public void fixBlockLighting() {
|
||||
while (!blocksToRelight.isEmpty()) {
|
||||
RelightBlockEntry current = blocksToRelight.entrySet().iterator().next().getValue();
|
||||
int bx = current.getX() << 4;
|
||||
int bz = current.getZ() << 4;
|
||||
while (!current.blocks.isEmpty()) {
|
||||
short coord = current.blocks.pollFirst();
|
||||
byte layer = MathMan.unpairShortX(coord);
|
||||
int y = MathMan.unpairShortY(coord) & 0xFF;
|
||||
int x = MathMan.unpair16x(layer);
|
||||
int z = MathMan.unpair16y(layer);
|
||||
int xx = bx + x;
|
||||
int zz = bz + z;
|
||||
int emit = queue.getEmmittedLight(xx, y, zz);
|
||||
if (emit < 1) {
|
||||
continue;
|
||||
}
|
||||
smoothBlockLight(emit, xx, y, zz, xx - 1, y, zz);
|
||||
smoothBlockLight(emit, xx, y, zz, xx + 1, y, zz);
|
||||
smoothBlockLight(emit, xx, y, zz, xx, y, zz - 1);
|
||||
smoothBlockLight(emit, xx, y, zz, xx, y, zz + 1);
|
||||
if (y > 0) {
|
||||
smoothBlockLight(emit, xx, y, zz, xx, y - 1, zz);
|
||||
}
|
||||
if (y < maxY) {
|
||||
smoothBlockLight(emit, xx, y, zz, xx, y + 1, zz);
|
||||
}
|
||||
}
|
||||
blocksToRelight.remove(current.coord);
|
||||
}
|
||||
updateBlockLight(this.lightQueue);
|
||||
}
|
||||
|
||||
public void sendChunks() {
|
||||
final Map<FaweChunk, int[]> fcs = new HashMap<>(skyToRelight.size());
|
||||
for (Map.Entry<Long, RelightSkyEntry> entry : skyToRelight.entrySet()) {
|
||||
RelightSkyEntry chunk = entry.getValue();
|
||||
CharFaweChunk fc = (CharFaweChunk) queue.getFaweChunk(chunk.x, chunk.z);
|
||||
Iterator<Long> iter = chunksToSend.iterator();
|
||||
while (iter.hasNext()) {
|
||||
long pair = iter.next();
|
||||
iter.remove();
|
||||
int x = MathMan.unpairIntX(pair);
|
||||
int z = MathMan.unpairIntY(pair);
|
||||
CharFaweChunk fc = (CharFaweChunk) queue.getFaweChunk(x, z);
|
||||
queue.sendChunk(fc);
|
||||
}
|
||||
}
|
||||
@ -136,19 +230,16 @@ public class NMSRelighter {
|
||||
return queue.getOpacity(x, y, z) < 15;
|
||||
}
|
||||
|
||||
public void lightBlock(int x, int y, int z, int brightness) {
|
||||
queue.setBlockLight(x, y, z, Math.max(15, brightness + 1));
|
||||
if (isTransparent(x - 1, y, z)) { queue.setBlockLight(x - 1, y, z, brightness); addBlock(x - 1, y, z); }
|
||||
if (isTransparent(x + 1, y, z)) { queue.setBlockLight(x + 1, y, z, brightness); addBlock(x + 1, y, z); }
|
||||
if (isTransparent(x, y, z - 1)) { queue.setBlockLight(x, y, z - 1, brightness); addBlock(x, y, z - 1); }
|
||||
if (isTransparent(x, y, z + 1)) { queue.setBlockLight(x, y, z + 1, brightness); addBlock(x, y, z + 1); }
|
||||
if (y > 0 && isTransparent(x, y - 1, z)) { queue.setBlockLight(x, y - 1, z, brightness); addBlock(x, y - 1, z); }
|
||||
if (y < maxY && isTransparent(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
|
||||
}
|
||||
|
||||
public void fixSkyLighting() {
|
||||
// Order chunks
|
||||
ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(skyToRelight.values());
|
||||
ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(skyToRelight.size());
|
||||
Iterator<Map.Entry<Long, RelightSkyEntry>> iter = skyToRelight.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Long, RelightSkyEntry> entry = iter.next();
|
||||
iter.remove();
|
||||
chunksToSend.add(entry.getKey());
|
||||
chunksList.add(entry.getValue());
|
||||
}
|
||||
Collections.sort(chunksList);
|
||||
int size = chunksList.size();
|
||||
if (size > DISPATCH_SIZE) {
|
||||
@ -189,7 +280,8 @@ public class NMSRelighter {
|
||||
int opacity = MathMan.unpair16x(pair);
|
||||
int brightness = MathMan.unpair16y(pair);
|
||||
if (brightness > 1 && (brightness != 15 || opacity != 15)) {
|
||||
lightBlock(bx + x, y, bz + z, brightness);
|
||||
addLightUpdate(bx + x, y, bz + z);
|
||||
// lightBlock(bx + x, y, bz + z, brightness);
|
||||
}
|
||||
switch (value) {
|
||||
case 0:
|
||||
@ -305,17 +397,9 @@ public class NMSRelighter {
|
||||
|
||||
private class RelightBlockEntry {
|
||||
public long coord;
|
||||
public ArrayDeque<Short> blocks;
|
||||
|
||||
public RelightBlockEntry(long pair) {
|
||||
this.coord = pair;
|
||||
this.blocks = new ArrayDeque<>(1);
|
||||
}
|
||||
|
||||
public void addBlock(int x, int y, int z) {
|
||||
byte layer = MathMan.pair16(x & 15, z & 15);
|
||||
short coord = MathMan.pairByte(layer, y);
|
||||
blocks.add(coord);
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
|
@ -0,0 +1,38 @@
|
||||
package com.boydti.fawe.example;
|
||||
|
||||
public class NullRelighter implements Relighter {
|
||||
|
||||
public static NullRelighter INSTANCE = new NullRelighter();
|
||||
|
||||
private NullRelighter() {}
|
||||
|
||||
@Override
|
||||
public boolean addChunk(int cx, int cz, boolean[] fix, int bitmask) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addLightUpdate(int x, int y, int z) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixLightingSafe(boolean sky) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixBlockLighting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixSkyLighting() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return true;
|
||||
}
|
||||
}
|
15
core/src/main/java/com/boydti/fawe/example/Relighter.java
Normal file
15
core/src/main/java/com/boydti/fawe/example/Relighter.java
Normal file
@ -0,0 +1,15 @@
|
||||
package com.boydti.fawe.example;
|
||||
|
||||
public interface Relighter {
|
||||
boolean addChunk(int cx, int cz, boolean[] fix, int bitmask);
|
||||
|
||||
void addLightUpdate(int x, int y, int z);
|
||||
|
||||
void fixLightingSafe(boolean sky);
|
||||
|
||||
void fixBlockLighting();
|
||||
|
||||
void fixSkyLighting();
|
||||
|
||||
boolean isEmpty();
|
||||
}
|
@ -5,6 +5,8 @@ import com.boydti.fawe.FaweAPI;
|
||||
import com.boydti.fawe.FaweCache;
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.NullRelighter;
|
||||
import com.boydti.fawe.example.Relighter;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
import com.boydti.fawe.util.MainUtil;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
@ -46,6 +48,10 @@ public abstract class FaweQueue {
|
||||
}
|
||||
}
|
||||
|
||||
public Relighter getRelighter() {
|
||||
return NullRelighter.INSTANCE;
|
||||
}
|
||||
|
||||
public enum ProgressType {
|
||||
QUEUE,
|
||||
DISPATCH,
|
||||
|
@ -64,6 +64,12 @@ public class MathMan {
|
||||
return (((long)x) << 32) | (y & 0xffffffffL);
|
||||
}
|
||||
|
||||
public static final short tripleBlockCoord(int x, int y, int z) {
|
||||
byte hi = (byte) ((x & 15) + ((z & 15) << 4));
|
||||
byte lo = (byte) y;
|
||||
return (short) (((hi & 0xFF) << 8) | (lo & 0xFF));
|
||||
}
|
||||
|
||||
public static final long chunkXZ2Int(int x, int z) {
|
||||
return (long)x & 4294967295L | ((long)z & 4294967295L) << 32;
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
#org.gradle.java.home=C:/PROGRA~2/Java/jdk1.7.0_79
|
||||
#org.gradle.java.home=C:/PROGRA~1/Java/jdk1.8.0_51
|
||||
org.gradle.daemon=true
|
||||
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.daemon=false
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.parallel=true
|
Loading…
Reference in New Issue
Block a user