Working async relighting

This commit is contained in:
Jesse Boyd 2016-07-27 08:03:51 +10:00
parent 23b67b3f56
commit ff60177dcc
24 changed files with 931 additions and 1093 deletions

View File

@ -5,10 +5,7 @@ import com.boydti.fawe.bukkit.FaweBukkit;
import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.example.NMSMappedFaweQueue; import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
@ -24,9 +21,7 @@ import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.world.ChunkUnloadEvent;
import org.bukkit.event.world.WorldInitEvent; import org.bukkit.event.world.WorldInitEvent;
public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMappedFaweQueue<World, CHUNK, CHUNKSECTIONS, SECTION> implements Listener { public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMappedFaweQueue<World, CHUNK, CHUNKSECTIONS, SECTION> implements Listener {
@ -45,30 +40,21 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
} }
@Override @Override
public void forEachMCA(RunnableVal<File> onEach) { public File getSaveFolder() {
File folder = new File(Bukkit.getWorldContainer(), getWorldName() + File.separator + "region"); return new File(Bukkit.getWorldContainer(), getWorldName() + File.separator + "region");
File[] regionFiles = folder.listFiles();
if (regionFiles == null) {
throw new RuntimeException("Could not find worlds folder: " + folder + " ? (no read access?)");
}
for (File file : regionFiles) {
String name = file.getName();
if (name.endsWith("mca")) {
onEach.run(file);
}
}
} }
@Override @Override
public void setFullbright(CHUNKSECTIONS sections) {} public void setFullbright(CHUNKSECTIONS sections) {}
@Override @Override
public boolean initLighting(CHUNK chunk, CHUNKSECTIONS sections, RelightMode mode) { public void relight(int x, int y, int z) {}
return false;
}
@Override @Override
public void relight(int x, int y, int z) {} public void relightBlock(int x, int y, int z) {}
@Override
public void relightSky(int x, int y, int z) {}
@Override @Override
public boolean removeLighting(CHUNKSECTIONS sections, RelightMode mode, boolean hasSky) { public boolean removeLighting(CHUNKSECTIONS sections, RelightMode mode, boolean hasSky) {
@ -84,27 +70,6 @@ public abstract class BukkitQueue_0<CHUNK, CHUNKSECTIONS, SECTION> extends NMSMa
} }
private static boolean registered = false; private static boolean registered = false;
@EventHandler(ignoreCancelled = true, priority = EventPriority.MONITOR)
public static void onChunkUnload(ChunkUnloadEvent event) {
Collection<FaweQueue> queues = SetQueue.IMP.getActiveQueues();
if (queues.isEmpty()) {
return;
}
String world = event.getWorld().getName();
Chunk chunk = event.getChunk();
long pair = MathMan.pairInt(chunk.getX(), chunk.getZ());
for (FaweQueue queue : queues) {
if (queue.getWorldName().equals(world)) {
Map<Long, Long> relighting = ((NMSMappedFaweQueue) queue).relighting;
if (!relighting.isEmpty() && relighting.containsKey(pair)) {
event.setCancelled(true);
return;
}
}
}
}
private static boolean disableChunkLoad = false; private static boolean disableChunkLoad = false;
@EventHandler @EventHandler

View File

@ -82,11 +82,6 @@ public class BukkitQueue_All extends BukkitQueue_0<Chunk, Chunk, Chunk> {
return chunk.getBlock(x, y, z).getLightLevel(); return chunk.getBlock(x, y, z).getLightLevel();
} }
@Override
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
return false;
}
@Override @Override
public Chunk getCachedSections(World impWorld, int cx, int cz) { public Chunk getCachedSections(World impWorld, int cx, int cz) {
return impWorld.getChunkAt(cx, cz); return impWorld.getChunkAt(cx, cz);

View File

@ -343,7 +343,7 @@ public class AsyncWorld implements World {
@Override @Override
@Deprecated @Deprecated
public boolean refreshChunk(int x, int z) { public boolean refreshChunk(int x, int z) {
queue.sendChunk(queue.getFaweChunk(x, z), FaweQueue.RelightMode.NONE); queue.sendChunk(queue.getFaweChunk(x, z));
return true; return true;
} }

View File

@ -6,7 +6,6 @@ import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
import com.boydti.fawe.example.CharFaweChunk; import com.boydti.fawe.example.CharFaweChunk;
import com.boydti.fawe.object.BytePair; import com.boydti.fawe.object.BytePair;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.IntegerPair;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
@ -47,6 +46,7 @@ import net.minecraft.server.v1_10_R1.EntityTrackerEntry;
import net.minecraft.server.v1_10_R1.EntityTypes; import net.minecraft.server.v1_10_R1.EntityTypes;
import net.minecraft.server.v1_10_R1.EnumDifficulty; import net.minecraft.server.v1_10_R1.EnumDifficulty;
import net.minecraft.server.v1_10_R1.EnumGamemode; import net.minecraft.server.v1_10_R1.EnumGamemode;
import net.minecraft.server.v1_10_R1.EnumSkyBlock;
import net.minecraft.server.v1_10_R1.IBlockData; import net.minecraft.server.v1_10_R1.IBlockData;
import net.minecraft.server.v1_10_R1.IDataManager; import net.minecraft.server.v1_10_R1.IDataManager;
import net.minecraft.server.v1_10_R1.MinecraftServer; import net.minecraft.server.v1_10_R1.MinecraftServer;
@ -85,7 +85,7 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
public BukkitQueue_1_10(final String world) { public BukkitQueue_1_10(final String world) {
super(world); super(world);
checkVersion("v1_10_R1"); checkVersion("v1_10_R1");
if (adapter == null) { if (air == null) {
try { try {
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a"); Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
fieldAir.setAccessible(true); fieldAir.setAccessible(true);
@ -222,6 +222,27 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
} }
} }
@Override
public int getOpacity(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return ibd.c();
}
@Override
public int getBrightness(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return ibd.d();
}
@Override
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return MathMan.pair16(ibd.c(), ibd.d());
}
@Override @Override
public void refreshChunk(World world, Chunk chunk) { public void refreshChunk(World world, Chunk chunk) {
if (!chunk.isLoaded()) { if (!chunk.isLoaded()) {
@ -304,13 +325,12 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
@Override @Override
public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) { public boolean removeLighting(ChunkSection[] sections, RelightMode mode, boolean sky) {
if (mode.ordinal() > 4) { if (mode != RelightMode.NONE) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
ChunkSection section = sections[i]; ChunkSection section = sections[i];
if (section != null) { if (section != null) {
section.a(new NibbleArray()); // Emitted section.a(new NibbleArray()); // Emitted
if (sky) { if (sky) {
System.out.println("REMOVE SKY");
section.b(new NibbleArray()); // Skylight section.b(new NibbleArray()); // Skylight
} }
} }
@ -319,142 +339,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
return true; return true;
} }
@Override
public boolean initLighting(Chunk chunk, ChunkSection[] sections, RelightMode mode) {
net.minecraft.server.v1_10_R1.Chunk c = ((CraftChunk) chunk).getHandle();
// Optimizations
// If it's all air, use the above light values
// If it's all solid, use no light values
World world = getWorld();
byte[] mask = new byte[256];
byte[] smoothArray = new byte[256];
Arrays.fill(mask, (byte) 15);
int bx = chunk.getX() << 4;
int bz = chunk.getZ() << 4;
section:
for (int y2 = 15; y2 >= 0; y2--) {
ChunkSection section = sections[y2];
if (section == null) {
continue;
}
int y = 16 + (y2 << 4);
DataPaletteBlock dataPalette = section.getBlocks();
layer:
for (int y1 = 15; y1 >= 0; y1--) {
y--;
boolean smooth = false;
index:
for (int j = 0; j < 256; j++) {
byte value = mask[j];
smoothArray[j] = 0;
int x = FaweCache.CACHE_X[y1][j];
int z = FaweCache.CACHE_Z[y1][j];
IBlockData ibd = dataPalette.a(x, y1, z);
int opacity = ibd.c();
if (x == 0 && z == 0) {
System.out.println(y + ": " + value + "," + opacity + " | " + getCombinedId4Data(bx + x, y, bz + z));
}
if (opacity != 0 && opacity >= value) {
mask[j] = 0;
continue index;
}
switch (value) {
case 0:
if (opacity != 0) {
continue index;
}
break;
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
case 14:
if (opacity == 0) {
mask[j] = --value;
if (x == 0 && z == 0) System.out.println(" - " + value);
} else {
mask[j] = value = (byte) Math.max(0, value - opacity);
if (x == 0 && z == 0) System.out.println(" - " + value);
}
break;
case 15:
if (opacity == 0) {
section.a(x, y1, z, value);
} else {
value -= opacity;
mask[j] = value;
section.a(x, y1, z, value);
if (x == 0 && z == 0) {
System.out.println(" - " + value);
}
}
continue index;
}
// Smooth
smooth = true;
smoothArray[j] = 1;
int adjacent = getAdjacentLight(bx + x, y, bz + z) - 1;
if (adjacent > value) {
if (x == 0 && z == 0) {
if (getSkyLight(bx + x - 1, y, bz + z) == 15) System.out.println("x-1");
if (getSkyLight(bx + x + 1, y, bz + z) == 15) System.out.println("x+1");
if (getSkyLight(bx + x, y, bz + z - 1) == 15) System.out.println("z-1");
if (getSkyLight(bx + x, y, bz + z + 1) == 15) System.out.println("z+1");
System.out.println("VALUE IS GREATER: " + getAdjacentLight(bx + x, y, bz + z));
}
value = (byte) adjacent;
mask[j] = value;
}
section.a(x, y1, z, value);
}
// if (smooth) {
// short[][] cache1 = FaweCache.CACHE_J[0];
// for (int x = 0; x < 16; x++) {
// int xx = bx + x;
// short[] cache2 = cache1[x];
// for (int z = 0; z < 16; z++) {
// int zz = bz + z;
// int j = cache2[z];
// if (smoothArray[j] == 0) {
// continue;
// }
// byte value = mask[j];
// int adjacent = getAdjacentLight(xx, y, zz) - 1;
// if (adjacent > value) {
// section.a(x, y1, z, mask[j] = (byte) adjacent);
// }
// }
// }
// for (int z = 15; z >=0; z--) {
// for (int x = 15; x >= 0; x--) {
// int xx = bx + x;
// int zz = bz + z;
// int j = cache1[x][z];
// if (smoothArray[j] == 0) {
// continue;
// }
// byte value = mask[j];
// int adjacent = getAdjacentLight(xx, y, zz) - 1;
// if (adjacent > value) {
// section.a(x, y1, z, mask[j] = (byte) adjacent);
// }
// }
// }
// }
}
}
return true;
}
@Override @Override
public void setFullbright(ChunkSection[] sections) { public void setFullbright(ChunkSection[] sections) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
@ -479,6 +363,18 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
return section.c(x & 15, y & 15, z & 15); return section.c(x & 15, y & 15, z & 15);
} }
@Override
public void relightBlock(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.SKY, pos);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.c(x, y, z); pos.c(x, y, z);
@ -873,7 +769,6 @@ public class BukkitQueue_1_10 extends BukkitQueue_0<Chunk, ChunkSection[], Chunk
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.minecraft.server.v1_7_R4.Block;
import net.minecraft.server.v1_7_R4.ChunkCoordIntPair; import net.minecraft.server.v1_7_R4.ChunkCoordIntPair;
import net.minecraft.server.v1_7_R4.ChunkPosition; import net.minecraft.server.v1_7_R4.ChunkPosition;
import net.minecraft.server.v1_7_R4.ChunkSection; import net.minecraft.server.v1_7_R4.ChunkSection;
@ -38,6 +39,7 @@ import net.minecraft.server.v1_7_R4.EntityTrackerEntry;
import net.minecraft.server.v1_7_R4.EntityTypes; import net.minecraft.server.v1_7_R4.EntityTypes;
import net.minecraft.server.v1_7_R4.EnumDifficulty; import net.minecraft.server.v1_7_R4.EnumDifficulty;
import net.minecraft.server.v1_7_R4.EnumGamemode; import net.minecraft.server.v1_7_R4.EnumGamemode;
import net.minecraft.server.v1_7_R4.EnumSkyBlock;
import net.minecraft.server.v1_7_R4.LongHashMap; import net.minecraft.server.v1_7_R4.LongHashMap;
import net.minecraft.server.v1_7_R4.MinecraftServer; import net.minecraft.server.v1_7_R4.MinecraftServer;
import net.minecraft.server.v1_7_R4.NBTTagCompound; import net.minecraft.server.v1_7_R4.NBTTagCompound;
@ -438,7 +440,6 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
} catch (Throwable e) { } catch (Throwable e) {
MainUtil.handleError(e); MainUtil.handleError(e);
} }
sendChunk(fc, null);
return true; return true;
} }
@ -600,56 +601,6 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
}); });
} }
@Override
public boolean initLighting(Chunk chunk, ChunkSection[] sections, RelightMode mode) {
net.minecraft.server.v1_7_R4.Chunk c = ((CraftChunk) chunk).getHandle();
if (mode == RelightMode.ALL) {
c.initLighting();
} else {
int i = c.h();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = c.b(x, y, z);
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ChunkSection section = sections[y >> 4];
if (section != null) {
section.setSkyLight(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override
public int getSkyLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.getSkyLight(x, y & 15, z);
}
@Override
public int getEmmittedLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.getEmittedLight(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
nmsWorld.t(x, y, z); nmsWorld.t(x, y, z);
@ -675,32 +626,54 @@ public class BukkitQueue17 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSec
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4; section.setSkyLight(x & 15, y & 15, z & 15, value);
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz);
ChunkSection section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkyLightArray().a(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4; section.setEmittedLight(x & 15, y & 15, z & 15, value);
int cz = z >> 4; }
if (!ensureChunkLoaded(cx, cz)) {
return; @Override
} public int getSkyLight(ChunkSection section, int x, int y, int z) {
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz); return section.getSkyLight(x & 15, y & 15, z & 15);
ChunkSection section = sections[y >> 4]; }
if (section == null) {
return; @Override
} public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value); return section.getEmittedLight(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ChunkSection section, int x, int y, int z) {
return section.getTypeId(x, y, z).k();
}
@Override
public int getBrightness(ChunkSection section, int x, int y, int z) {
return section.getTypeId(x, y, z).m();
}
@Override
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
return section.getIdArray()[i] != 0;
}
@Override
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
Block block = section.getTypeId(x, y, z);
return MathMan.pair16(block.k(), block.m());
}
@Override
public void relightBlock(int x, int y, int z) {
nmsWorld.c(EnumSkyBlock.BLOCK, x, y, z);
}
@Override
public void relightSky(int x, int y, int z) {
nmsWorld.c(EnumSkyBlock.SKY, x, y, z);
} }
} }

View File

@ -28,6 +28,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.minecraft.server.v1_8_R3.Block;
import net.minecraft.server.v1_8_R3.BlockPosition; import net.minecraft.server.v1_8_R3.BlockPosition;
import net.minecraft.server.v1_8_R3.ChunkCoordIntPair; import net.minecraft.server.v1_8_R3.ChunkCoordIntPair;
import net.minecraft.server.v1_8_R3.ChunkSection; import net.minecraft.server.v1_8_R3.ChunkSection;
@ -37,6 +38,7 @@ import net.minecraft.server.v1_8_R3.EntityTracker;
import net.minecraft.server.v1_8_R3.EntityTrackerEntry; import net.minecraft.server.v1_8_R3.EntityTrackerEntry;
import net.minecraft.server.v1_8_R3.EntityTypes; import net.minecraft.server.v1_8_R3.EntityTypes;
import net.minecraft.server.v1_8_R3.EnumDifficulty; import net.minecraft.server.v1_8_R3.EnumDifficulty;
import net.minecraft.server.v1_8_R3.EnumSkyBlock;
import net.minecraft.server.v1_8_R3.LongHashMap; import net.minecraft.server.v1_8_R3.LongHashMap;
import net.minecraft.server.v1_8_R3.MinecraftServer; import net.minecraft.server.v1_8_R3.MinecraftServer;
import net.minecraft.server.v1_8_R3.NBTTagCompound; import net.minecraft.server.v1_8_R3.NBTTagCompound;
@ -63,7 +65,7 @@ import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]> { public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
public BukkitQueue18R3(final String world) { public BukkitQueue18R3(final String world) {
super(world); super(world);
@ -113,7 +115,8 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
} }
@Override @Override
public int getCombinedId4Data(char[] ls, int x, int y, int z) { public int getCombinedId4Data(ChunkSection section, int x, int y, int z) {
char[] ls = section.getIdArray();
return ls[FaweCache.CACHE_J[y][x & 15][z & 15]]; return ls[FaweCache.CACHE_J[y][x & 15][z & 15]];
} }
@ -123,9 +126,8 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
} }
@Override @Override
public char[] getCachedSection(ChunkSection[] chunkSections, int cy) { public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
ChunkSection section = chunkSections[cy]; return chunkSections[cy];
return section == null ? null : section.getIdArray();
} }
@Override @Override
@ -413,7 +415,6 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
} catch (Throwable e) { } catch (Throwable e) {
MainUtil.handleError(e); MainUtil.handleError(e);
} }
sendChunk(fc, null);
return true; return true;
} }
@ -585,56 +586,6 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
}); });
} }
@Override
public boolean initLighting(Chunk chunk, ChunkSection[] sections, RelightMode mode) {
net.minecraft.server.v1_8_R3.Chunk c = ((CraftChunk) chunk).getHandle();
if (mode == RelightMode.ALL) {
c.initLighting();
} else {
int i = c.g();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = c.getTypeAbs(x, y, z).p();
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ChunkSection section = sections[y >> 4];
if (section != null) {
section.a(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override
public int getSkyLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.d(x, y & 15, z);
}
@Override
public int getEmmittedLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.e(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.c(x, y, z); pos.c(x, y, z);
@ -661,32 +612,70 @@ public class BukkitQueue18R3 extends BukkitQueue_0<Chunk, ChunkSection[], char[]
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4; section.a(x & 15, y & 15, z & 15, value);
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz);
ChunkSection section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkyLightArray().a(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4; section.b(x & 15, y & 15, z & 15, value);
int cz = z >> 4; }
if (!ensureChunkLoaded(cx, cz)) {
return; @Override
public int getSkyLight(ChunkSection section, int x, int y, int z) {
return section.d(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
return section.e(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ChunkSection section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
} }
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz); Block block = Block.getById(FaweCache.getId(combined));
ChunkSection section = sections[y >> 4]; return block.p();
if (section == null) { }
return;
@Override
public int getBrightness(ChunkSection section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
} }
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value); Block block = Block.getById(FaweCache.getId(combined));
return block.r();
}
@Override
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
return section.getIdArray()[i] != 0;
}
@Override
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getById(FaweCache.getId(combined));
return MathMan.pair16(block.p(), block.r());
}
@Override
public void relightBlock(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.SKY, pos);
} }
} }

View File

@ -46,6 +46,7 @@ import net.minecraft.server.v1_9_R2.EntityTracker;
import net.minecraft.server.v1_9_R2.EntityTrackerEntry; import net.minecraft.server.v1_9_R2.EntityTrackerEntry;
import net.minecraft.server.v1_9_R2.EntityTypes; import net.minecraft.server.v1_9_R2.EntityTypes;
import net.minecraft.server.v1_9_R2.EnumDifficulty; 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.IBlockData;
import net.minecraft.server.v1_9_R2.IDataManager; import net.minecraft.server.v1_9_R2.IDataManager;
import net.minecraft.server.v1_9_R2.MinecraftServer; import net.minecraft.server.v1_9_R2.MinecraftServer;
@ -76,24 +77,29 @@ import org.bukkit.event.world.WorldInitEvent;
import org.bukkit.event.world.WorldLoadEvent; import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], DataPaletteBlock> { public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], ChunkSection> {
private IBlockData air; private static IBlockData air;
private static Field fieldBits;
public BukkitQueue_1_9_R1(final String world) { public BukkitQueue_1_9_R1(final String world) {
super(world); super(world);
checkVersion("v1_9_R2"); checkVersion("v1_9_R2");
try { if (air == null) {
Field fieldAir = DataPaletteBlock.class.getDeclaredField("a"); try {
fieldAir.setAccessible(true); Field fieldAir = DataPaletteBlock.class.getDeclaredField("a");
air = (IBlockData) fieldAir.get(null); fieldAir.setAccessible(true);
if (adapter == null) { air = (IBlockData) fieldAir.get(null);
setupAdapter(new FaweAdapter_1_9()); fieldBits = DataPaletteBlock.class.getDeclaredField("b");
Fawe.debug("Using adapter: " + adapter); fieldBits.setAccessible(true);
Fawe.debug("========================================="); if (adapter == null) {
setupAdapter(new FaweAdapter_1_9());
Fawe.debug("Using adapter: " + adapter);
Fawe.debug("=========================================");
}
} catch (Throwable e) {
throw new RuntimeException(e);
} }
} catch (Throwable e) {
throw new RuntimeException(e);
} }
} }
@ -104,14 +110,14 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
} }
@Override @Override
public DataPaletteBlock getCachedSection(ChunkSection[] chunkSections, int cy) { public ChunkSection getCachedSection(ChunkSection[] chunkSections, int cy) {
ChunkSection nibble = chunkSections[cy]; return chunkSections[cy];
return nibble != null ? nibble.getBlocks() : null;
} }
@Override @Override
public int getCombinedId4Data(DataPaletteBlock lastSection, int x, int y, int z) { public int getCombinedId4Data(ChunkSection lastSection, int x, int y, int z) {
IBlockData ibd = lastSection.a(x & 15, y & 15, z & 15); DataPaletteBlock dataPalette = lastSection.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
Block block = ibd.getBlock(); Block block = ibd.getBlock();
int id = Block.getId(block); int id = Block.getId(block);
if (FaweCache.hasData(id)) { if (FaweCache.hasData(id)) {
@ -294,56 +300,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
return true; return true;
} }
@Override
public boolean initLighting(Chunk chunk, ChunkSection[] sections, RelightMode mode) {
net.minecraft.server.v1_9_R2.Chunk c = ((CraftChunk) chunk).getHandle();
if (mode == RelightMode.ALL) {
c.initLighting();
} else {
int i = c.g();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = c.a(x, y, z).c();
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ChunkSection section = sections[y >> 4];
if (section != null) {
section.a(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override
public int getSkyLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.b(x, y & 15, z);
}
@Override
public int getEmmittedLight(ChunkSection[] sections, int x, int y, int z) {
ChunkSection section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.c(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.c(x, y, z); pos.c(x, y, z);
@ -773,7 +729,6 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }
@ -793,32 +748,74 @@ public class BukkitQueue_1_9_R1 extends BukkitQueue_0<Chunk, ChunkSection[], Dat
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz);
ChunkSection section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkyLightArray().a(x & 15, y & 15, z & 15, value); section.getSkyLightArray().a(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ChunkSection section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ChunkSection[] sections = getCachedSections(getWorld(), cx, cz);
ChunkSection section = sections[y >> 4];
if (section == null) {
return;
}
section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value); section.getEmittedLightArray().a(x & 15, y & 15, z & 15, value);
} }
@Override
public int getSkyLight(ChunkSection section, int x, int y, int z) {
return section.b(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ChunkSection section, int x, int y, int z) {
return section.c(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return ibd.c();
}
@Override
public int getBrightness(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return ibd.d();
}
@Override
public int getOpacityBrightnessPair(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPalette = section.getBlocks();
IBlockData ibd = dataPalette.a(x & 15, y & 15, z & 15);
return MathMan.pair16(ibd.c(), ibd.d());
}
private DataBits lastBits;
private DataPaletteBlock lastBlocks;
@Override
public boolean hasBlock(ChunkSection section, int x, int y, int z) {
DataPaletteBlock dataPaletteBlock = section.getBlocks();
try {
if (lastBlocks != dataPaletteBlock) {
lastBits = (DataBits) fieldBits.get(dataPaletteBlock);
lastBlocks = dataPaletteBlock;
}
int i = FaweCache.CACHE_J[y][x & 15][z & 15];
return lastBits.a(i) != 0;
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return false;
}
@Override
public void relightBlock(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.c(x, y, z);
nmsWorld.c(EnumSkyBlock.SKY, pos);
}
} }

View File

@ -56,7 +56,6 @@ import java.util.UUID;
import java.util.zip.GZIPInputStream; import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream; import java.util.zip.GZIPOutputStream;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import org.bukkit.Chunk;
import org.bukkit.Location; import org.bukkit.Location;
/** /**
@ -356,27 +355,27 @@ public class FaweAPI {
return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2)); return (version[0] > major) || ((version[0] == major) && (version[1] > minor)) || ((version[0] == major) && (version[1] == minor) && (version[2] >= minor2));
} }
/** // /**
* Fix the lighting in a chunk // * Fix the lighting in a chunk
* @param world // * @param world
* @param x // * @param x
* @param z // * @param z
* @param mode // * @param mode
*/ // */
public static void fixLighting(String world, int x, int z, FaweQueue.RelightMode mode) { // public static void fixLighting(String world, int x, int z, FaweQueue.RelightMode mode) {
FaweQueue queue = SetQueue.IMP.getNewQueue(world, true, false); // FaweQueue queue = SetQueue.IMP.getNewQueue(world, true, false);
queue.fixLighting(queue.getFaweChunk(x, z), mode); // queue.fixLighting(queue.getFaweChunk(x, z), mode);
} // }
//
/** // /**
* Fix the lighting in a chunk // * Fix the lighting in a chunk
* @param chunk // * @param chunk
* @param mode // * @param mode
*/ // */
public static void fixLighting(final Chunk chunk, FaweQueue.RelightMode mode) { // public static void fixLighting(final Chunk chunk, FaweQueue.RelightMode mode) {
FaweQueue queue = SetQueue.IMP.getNewQueue(chunk.getWorld().getName(), true, false); // FaweQueue queue = SetQueue.IMP.getNewQueue(chunk.getWorld().getName(), true, false);
queue.fixLighting(queue.getFaweChunk(chunk.getX(), chunk.getZ()), mode); // queue.fixLighting(queue.getFaweChunk(chunk.getX(), chunk.getZ()), mode);
} // }
public static int fixLighting(String world, Region selection) { public static int fixLighting(String world, Region selection) {
return fixLighting(world, selection, FaweQueue.RelightMode.ALL); return fixLighting(world, selection, FaweQueue.RelightMode.ALL);
@ -409,48 +408,21 @@ public class FaweAPI {
NMSRelighter relighter = new NMSRelighter(nmsQueue); NMSRelighter relighter = new NMSRelighter(nmsQueue);
for (int x = minX; x <= maxX; x++) { for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z ++) { for (int z = minZ; z <= maxZ; z ++) {
relighter.addChunk(x, z); relighter.addChunk(x, z, null);
count++;
} }
} }
boolean sky = nmsQueue.hasSky(); if (mode != FaweQueue.RelightMode.NONE) {
if (sky) { boolean sky = nmsQueue.hasSky();
relighter.fixSkyLighting(); if (sky) {
relighter.fixSkyLighting();
}
relighter.fixBlockLighting();
} else {
relighter.removeLighting();
} }
relighter.fixBlockLighting(); relighter.sendChunks();
} }
// ArrayList<Thread> threads = new ArrayList<>();
// for (int X = 0; X < 2; X++) {
// for (int Z = 0; Z < 2; Z++) {
// for (int x = minX + X; x <= maxX; x += 2) {
// for (int z = minZ + Z; z <= maxZ; z += 2) {
// final FaweChunk<?> chunk = queue.getFaweChunk(x, z);
// if (Settings.LIGHTING.ASYNC) {
// Thread thread = new Thread(new Runnable() {
// @Override
// public void run() {
// queue.fixLightingSafe(chunk, mode);
// queue.sendChunk(chunk, FaweQueue.RelightMode.NONE);
// }
// });
// thread.start();
// threads.add(thread);
// } else {
// queue.fixLightingSafe(chunk, mode);
// queue.sendChunk(chunk, FaweQueue.RelightMode.NONE);
// }
// count++;
// }
// }
// for (Thread thread : threads) {
// try {
// thread.join();
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// threads.clear();
// }
// }
return count; return count;
} }

View File

@ -23,6 +23,7 @@ public enum BBC {
PREFIX("&8(&4&lFAWE&8)&7", "Info"), PREFIX("&8(&4&lFAWE&8)&7", "Info"),
SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"), SCHEMATIC_PASTING("&7The schematic is pasting. This cannot be undone.", "Info"),
FIX_LIGHTING_SELECTION("&7Lighting has been fixed in %s0 chunks. (It may take a second for the packets to send)", "Info"), FIX_LIGHTING_SELECTION("&7Lighting has been fixed in %s0 chunks. (It may take a second for the packets to send)", "Info"),
UPDATED_LIGHTING_SELECTION("&7Lighting has been updated in %s0 chunks. (It may take a second for the packets to send)", "Info"),
SET_REGION("&7Selection set to your current WorldEdit region", "Info"), SET_REGION("&7Selection set to your current WorldEdit region", "Info"),
WORLDEDIT_COMMAND_LIMIT("&7Please wait until your current action completes", "Info"), WORLDEDIT_COMMAND_LIMIT("&7Please wait until your current action completes", "Info"),
WORLDEDIT_DELAYED("&7Please wait while we process your WorldEdit action...", "Info"), WORLDEDIT_DELAYED("&7Please wait while we process your WorldEdit action...", "Info"),

View File

@ -210,13 +210,10 @@ public class Settings extends Config {
@Comment({ @Comment({
"The relighting mode to use:", "The relighting mode to use:",
" - 0 = None (Do no relighting)", " - 0 = None (Do no relighting)",
" - 1 = Shadowless (Removes shadows)", " - 1 = Optimal (Relight changed light sources and changed blocks)",
" - 2 = Minimal (Relight changed light sources)", " - 2 = All (Slowly relight every blocks)"
" - 3 = Fullbright (Relight changed light sources, remove shadows)",
" - 4 = Optimal (Relight changed light sources and changed blocks)",
" - 5 = All (Slowly relight every blocks)"
}) })
public static int MODE = 4; public static int MODE = 1;
} }
public static void save(File file) { public static void save(File file) {

View File

@ -9,6 +9,7 @@ import com.boydti.fawe.object.IntegerPair;
import com.boydti.fawe.object.RunnableVal; import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -444,9 +445,25 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
} }
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(FaweCache.getId(combined)); BlockMaterial block = BundledBlockData.getInstance().getMaterialById(FaweCache.getId(combined));
if (block == null) { if (block == null) {
return 255; return 15;
} }
return block.getLightOpacity(); return Math.min(15, block.getLightOpacity());
}
public int getBrightness(SECTION section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(FaweCache.getId(combined));
if (block == null) {
return 15;
}
return Math.min(15, block.getLightValue());
}
public int getOpacityBrightnessPair(SECTION section, int x, int y, int z) {
return MathMan.pair16(Math.min(15, getOpacity(section, x, y, z)), getBrightness(section, x, y, z));
} }
public abstract int getSkyLight(SECTION sections, int x, int y, int z); public abstract int getSkyLight(SECTION sections, int x, int y, int z);
@ -562,6 +579,58 @@ public abstract class MappedFaweQueue<WORLD, CHUNK, SECTION> extends FaweQueue {
return getOpacity(lastSection, x, y, z); return getOpacity(lastSection, x, y, z);
} }
@Override
public int getOpacityBrightnessPair(int x, int y, int z) {
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)) {
return 0;
}
lastChunkSections = getCachedSections(getWorld(), cx, cz);
lastSection = getCachedSection(lastChunkSections, cy);
} else if (cy != lastChunkY) {
if (lastChunkSections == null) {
return 0;
}
lastSection = getCachedSection(lastChunkSections, cy);
}
if (lastSection == null) {
return 0;
}
return getOpacityBrightnessPair(lastSection, x, y, z);
}
@Override
public int getBrightness(int x, int y, int z) {
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)) {
return 0;
}
lastChunkSections = getCachedSections(getWorld(), cx, cz);
lastSection = getCachedSection(lastChunkSections, cy);
} else if (cy != lastChunkY) {
if (lastChunkSections == null) {
return 0;
}
lastSection = getCachedSection(lastChunkSections, cy);
}
if (lastSection == null) {
return 0;
}
return getBrightness(lastSection, x, y, z);
}
@Override @Override
public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException { public int getCombinedId4Data(int x, int y, int z) throws FaweException.FaweChunkLoadException {
int cx = x >> 4; int cx = x >> 4;

View File

@ -1,70 +1,78 @@
package com.boydti.fawe.example; package com.boydti.fawe.example;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings; import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> extends MappedFaweQueue<WORLD, CHUNKSECTION, SECTION> { public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> extends MappedFaweQueue<WORLD, CHUNKSECTION, SECTION> {
public NMSMappedFaweQueue(String world) { public NMSMappedFaweQueue(String world) {
super(world); super(world);
} }
public boolean isRelighting(int x, int z) { private NMSRelighter relighter;
long pair = MathMan.pairInt(x, z);
return relighting.contains(pair) || blocks.contains(pair);
}
public final ConcurrentHashMap<Long, Long> relighting = new ConcurrentHashMap<>();
@Override @Override
public void sendChunk(final FaweChunk fc, RelightMode mode) { public boolean execute(FaweChunk fc) {
if (mode == null) { if (super.execute(fc)) {
mode = FaweQueue.RelightMode.values()[Settings.LIGHTING.MODE]; sendChunk(fc);
} if (Settings.LIGHTING.MODE == 0) {
final RelightMode finalMode = mode; return true;
TaskManager.IMP.taskSoonMain(new Runnable() {
@Override
public void run() {
final long pair = fc.longHash();
relighting.put(pair, pair);
final boolean result = finalMode == RelightMode.NONE || fixLighting(fc, finalMode);
TaskManager.IMP.taskNowMain(new Runnable() {
@Override
public void run() {
if (!result) {
fixLighting(fc, finalMode);
}
CHUNK chunk = (CHUNK) fc.getChunk();
refreshChunk(getWorld(), chunk);
relighting.remove(pair);
if (relighting.isEmpty() && chunks.isEmpty()) {
runTasks();
}
}
}, false);
} }
}, Settings.LIGHTING.ASYNC); if (relighter == null) {
relighter = new NMSRelighter(this);
}
if (Settings.LIGHTING.MODE == 2) {
relighter.addChunk(fc.getX(), fc.getZ(), null);
return true;
}
CharFaweChunk chunk = (CharFaweChunk) fc;
boolean relight = false;
boolean[] fix = new boolean[16];
boolean sky = hasSky();
for (int i = 0; i < 16; i++) {
if ((sky && ((chunk.getAir(i) & 4095) != 0 || (chunk.getCount(i) & 4095) != 0)) || chunk.getRelight(i) != 0) {
relight = true;
fix[i] = true;
}
}
if (relight) {
relighter.addChunk(chunk.getX(), chunk.getZ(), fix);
}
return true;
} else {
return false;
}
}
@Override
public void runTasks() {
super.runTasks();
if (relighter != null) {
boolean sky = hasSky();
if (sky) {
relighter.fixSkyLighting();
}
relighter.fixBlockLighting();
relighter.sendChunks();
}
}
@Override
public void sendChunk(final FaweChunk fc) {
refreshChunk(getWorld(), (CHUNK) fc.getChunk());
} }
public abstract void setFullbright(CHUNKSECTION sections); public abstract void setFullbright(CHUNKSECTION sections);
public abstract boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky); public abstract boolean removeLighting(CHUNKSECTION sections, RelightMode mode, boolean hasSky);
public abstract boolean initLighting(CHUNK chunk, CHUNKSECTION sections, RelightMode mode);
public boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) { public boolean isSurrounded(final char[][] sections, final int x, final int y, final int z) {
return this.isSolid(this.getId(sections, x, y + 1, z)) return this.isSolid(this.getId(sections, x, y + 1, z))
&& this.isSolid(this.getId(sections, x + 1, y - 1, z)) && this.isSolid(this.getId(sections, x + 1, y - 1, z))
@ -95,6 +103,10 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
public abstract void relight(int x, int y, int z); public abstract void relight(int x, int y, int z);
public abstract void relightBlock(int x, int y, int z);
public abstract void relightSky(int x, int y, int z);
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(int x, int y, int z, int value) {
int cx = x >> 4; int cx = x >> 4;
int cz = z >> 4; int cz = z >> 4;
@ -147,174 +159,6 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
public abstract void setBlockLight(SECTION section, int x, int y, int z, int value); public abstract void setBlockLight(SECTION section, int x, int y, int z, int value);
@Override
public boolean fixLighting(FaweChunk<?> fc, RelightMode mode) {
if (mode == RelightMode.NONE) {
return true;
}
try {
boolean async = Fawe.get().getMainThread() != Thread.currentThread();
int cx = fc.getX();
int cz = fc.getZ();
if (!isChunkLoaded(cx, cz)) {
if (async) {
return false;
}
loadChunk(getWorld(), cx, cz, false);
}
// Load adjacent
for (int x = -1; x <= 1; x++) {
for (int z = -1; z <= 1; z++) {
if (x == 0 && z == 0) {
continue;
}
if (mode.ordinal() > 3 && !isChunkLoaded(cx + 1, cz)) {
if (async) {
final int cxx = cx + x;
final int czz = cz + z;
TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
loadChunk(getWorld(), cxx, czz, false);
}
});
} else {
loadChunk(getWorld(), cx + x, cz + z, false);
}
}
}
}
CHUNKSECTION sections = getCachedSections(getWorld(), cx, cz);
boolean hasSky = hasSky();
if (mode.ordinal() < 3) {
if (hasSky) {
setFullbright(sections);
}
}
CHUNK impChunk = (CHUNK) fc.getChunk();
removeLighting(sections, mode, hasSky);
if (hasSky) {
initLighting(impChunk, sections, mode);
}
if (mode == RelightMode.SHADOWLESS) {
return true;
}
CharFaweChunk bc = (CharFaweChunk) fc;
if (((bc.getTotalRelight() != 0) || mode.ordinal() > 3)) {
if (mode == RelightMode.ALL) {
bc = getPrevious(bc, sections, null, null, null, true);
}
int total = bc.getTotalCount();
final int X = cx << 4;
final int Z = cz << 4;
for (int j = 15; j >= 0; j--) {
if (((bc.getRelight(j) == 0) && mode.ordinal() <= 3) || (bc.getCount(j) == 0 && mode != RelightMode.ALL) || ((bc.getCount(j) >= 4096) && (bc.getAir(j) == 0)) || bc.getAir(j) == 4096) {
continue;
}
final char[] array = bc.getIdArray(j);
if (array == null) {
continue;
}
switch (mode) {
case ALL: {
}
// for (int k = 4095; k >= 0; k--) {
// final int x = FaweCache.CACHE_X[j][k];
// final int y = FaweCache.CACHE_Y[j][k];
// if (y == 0) {
// continue;
// }
// final int z = FaweCache.CACHE_Z[j][k];
// final int i = array[k];
// final short id = (short) (i >> 4);
// switch (FaweCache.getLight(id)) {
// case OCCLUDING:
// if (y == 0 || !FaweCache.isTransparent(bc.getCombinedId(x, y - 1, z) >> 4)) {
// continue;
// }
// break;
// case TRANSPARENT_EMIT:
// case SOLID_EMIT:
// if (this.isSurrounded(bc.getCombinedIdArrays(), x, y, z)) {
// continue;
// }
// break;
// case TRANSPARENT:
// if (y >= 255) {
// continue;
// }
// int light = getSkyLight(sections, x, y, z);
// if (light != 0) {
// continue;
// }
// break;
// }
// relight(X + x, y, Z + z);
// }
// break;
// }
case OPTIMAL: {
for (int k = 4095; k >= 0; k--) {
final int x = FaweCache.CACHE_X[j][k];
final int y = FaweCache.CACHE_Y[j][k];
if (y == 0) {
continue;
}
final int z = FaweCache.CACHE_Z[j][k];
final int i = array[k];
final short id = (short) (i >> 4);
switch (FaweCache.getLight(id)) {
case OCCLUDING:
if (y == 0 || !FaweCache.isTransparent(bc.getCombinedId(x, y - 1, z) >> 4)) {
continue;
}
break;
case TRANSPARENT_EMIT:
case SOLID_EMIT:
if (this.isSurrounded(bc.getCombinedIdArrays(), x, y, z)) {
continue;
}
break;
case TRANSPARENT:
continue;
}
relight(X + x, y, Z + z);
}
break;
}
case FULLBRIGHT:
case MINIMAL: {
for (int k = 4095; k >= 0; k--) {
final int x = FaweCache.CACHE_X[j][k];
final int y = FaweCache.CACHE_Y[j][k];
final int z = FaweCache.CACHE_Z[j][k];
final int i = array[k];
final short id = (short) (i >> 4);
switch (FaweCache.getLight(id)) {
case TRANSPARENT:
case OCCLUDING:
continue;
case TRANSPARENT_EMIT:
case SOLID_EMIT:
if (this.isSurrounded(bc.getCombinedIdArrays(), x, y, z)) {
continue;
}
}
relight(X + x, y, Z + z);
}
break;
}
}
}
}
return true;
} catch (Throwable ignore) {
ignore.printStackTrace();
}
return false;
}
public abstract void refreshChunk(WORLD world, CHUNK chunk); public abstract void refreshChunk(WORLD world, CHUNK chunk);
public abstract CharFaweChunk getPrevious(CharFaweChunk fs, CHUNKSECTION sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception; public abstract CharFaweChunk getPrevious(CharFaweChunk fs, CHUNKSECTION sections, Map<?, ?> tiles, Collection<?>[] entities, Set<UUID> createdEntities, boolean all) throws Exception;
@ -338,12 +182,4 @@ public abstract class NMSMappedFaweQueue<WORLD, CHUNK, CHUNKSECTION, SECTION> ex
} }
return getTileEntity(lastChunk, x, y, z); return getTileEntity(lastChunk, x, y, z);
} }
@Override
public int size() {
if (chunks.size() == 0 && SetQueue.IMP.getStage(this) != SetQueue.QueueStage.INACTIVE && relighting.isEmpty()) {
runTasks();
}
return chunks.size();
}
} }

View File

@ -1,62 +1,164 @@
package com.boydti.fawe.example; package com.boydti.fawe.example;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.MathMan; import com.boydti.fawe.util.MathMan;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map;
public class NMSRelighter { public class NMSRelighter {
private final NMSMappedFaweQueue queue; private final NMSMappedFaweQueue queue;
private final HashMap<Long, RelightChunk> toRelight; private final HashMap<Long, RelightSkyEntry> skyToRelight;
private final HashMap<Long, RelightBlockEntry> blocksToRelight;
public NMSRelighter(NMSMappedFaweQueue queue) { public NMSRelighter(NMSMappedFaweQueue queue) {
this.queue = queue; this.queue = queue;
toRelight = new HashMap<>(); skyToRelight = new HashMap<>();
blocksToRelight = new HashMap<>();
} }
public boolean addChunk(int cx, int cz) { public boolean addChunk(int cx, int cz, boolean[] fix) {
long pair = MathMan.pairInt(cx, cz); long pair = MathMan.pairInt(cx, cz);
if (toRelight.containsKey(pair)) { if (skyToRelight.containsKey(pair)) {
return false; return false;
} }
toRelight.put(pair, new RelightChunk(cx, cz)); skyToRelight.put(pair, new RelightSkyEntry(cx, cz, fix));
return true; return true;
} }
public void removeLighting() {
for (Map.Entry<Long, RelightSkyEntry> entry : skyToRelight.entrySet()) {
RelightSkyEntry chunk = entry.getValue();
queue.ensureChunkLoaded(chunk.x, chunk.z);
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
queue.removeLighting(sections, FaweQueue.RelightMode.ALL, queue.hasSky());
}
}
public void addBlock(int x, int y, int z) {
if (y < 1) {
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);
}
public void smoothBlockLight(int emit, int x, int y, int z, int rx, int ry, int rz) {
if (queue.hasBlock(rx, ry, rz)) {
return;
}
int emitAdjacent = queue.getEmmittedLight(rx, ry, rz);
if (emit - emitAdjacent > 2) {
queue.setBlockLight(rx, ry, rz, emit - 1);
addBlock(rx, ry, rz);
}
}
public void fixBlockLighting() { public void fixBlockLighting() {
// TODO 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;
if (y < 0) {
System.out.println(y);
}
int emit = queue.getEmmittedLight(xx, y, zz);
if (emit < 2) {
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 < 255) {
smoothBlockLight(emit, xx, y, zz, xx, y + 1, zz);
}
}
blocksToRelight.remove(current.coord);
}
}
public void sendChunks() {
for (Map.Entry<Long, RelightSkyEntry> entry : skyToRelight.entrySet()) {
RelightSkyEntry chunk = entry.getValue();
queue.sendChunk(queue.getFaweChunk(chunk.x, chunk.z));
}
}
public void lightBlock(int x, int y, int z, int brightness) {
queue.setBlockLight(x, y, z, Math.max(15, brightness + 1));
if (!queue.hasBlock(x - 1, y, z)) { queue.setBlockLight(x - 1, y, z, brightness); addBlock(x - 1, y, z); }
if (!queue.hasBlock(x + 1, y, z)) { queue.setBlockLight(x + 1, y, z, brightness); addBlock(x + 1, y, z); }
if (!queue.hasBlock(x, y, z - 1)) { queue.setBlockLight(x, y, z - 1, brightness); addBlock(x, y, z - 1); }
if (!queue.hasBlock(x, y, z + 1)) { queue.setBlockLight(x, y, z + 1, brightness); addBlock(x, y, z + 1); }
if (y > 0 && !queue.hasBlock(x, y - 1, z)) { queue.setBlockLight(x, y - 1, z, brightness); addBlock(x, y - 1, z); }
if (y < 255 && !queue.hasBlock(x, y + 1, z)) { queue.setBlockLight(x, y + 1, z, brightness); addBlock(x, y + 1, z); }
} }
public void fixSkyLighting() { public void fixSkyLighting() {
// Order chunks // Order chunks
ArrayList<RelightChunk> chunksList = new ArrayList<>(toRelight.values()); ArrayList<RelightSkyEntry> chunksList = new ArrayList<>(skyToRelight.values());
Collections.sort(chunksList); Collections.sort(chunksList);
RelightChunk[] chunks = chunksList.toArray(new RelightChunk[chunksList.size()]); RelightSkyEntry[] chunks = chunksList.toArray(new RelightSkyEntry[chunksList.size()]);
byte[] cacheX = FaweCache.CACHE_X[0]; byte[] cacheX = FaweCache.CACHE_X[0];
byte[] cacheZ = FaweCache.CACHE_Z[0]; byte[] cacheZ = FaweCache.CACHE_Z[0];
for (int y = 255; y >= 0; y--) { for (int y = 255; y > 0; y--) {
for (RelightChunk chunk : chunks) { // Propogate skylight for (RelightSkyEntry chunk : chunks) { // Propogate skylight
int layer = y >> 4;
if (!chunk.fix[layer]) {
continue;
}
int bx = chunk.x << 4;
int bz = chunk.z << 4;
byte[] mask = chunk.mask; byte[] mask = chunk.mask;
queue.ensureChunkLoaded(chunk.x, chunk.z);
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z); Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
if (sections == null) continue; if (sections == null) continue;
Object section = queue.getCachedSection(sections, y >> 4); Object section = queue.getCachedSection(sections, layer);
if (section == null) continue; if (section == null) continue;
chunk.smooth = false; chunk.smooth = false;
for (int j = 0; j < 256; j++) { for (int j = 0; j < 256; j++) {
int x = cacheX[j]; int x = cacheX[j];
int z = cacheZ[j]; int z = cacheZ[j];
byte value = mask[j]; byte value = mask[j];
int opacity = queue.getOpacity(section, x, y, z); byte pair = (byte) queue.getOpacityBrightnessPair(section, x, y, z);
int opacity = MathMan.unpair16x(pair);
int brightness = MathMan.unpair16y(pair);
if (brightness > 1 && (brightness != 15 || opacity != 15)) {
lightBlock(bx + x, y, bz + z, brightness);
}
if (opacity != 0 && opacity >= value) { if (opacity != 0 && opacity >= value) {
mask[j] = 0; mask[j] = 0;
queue.setSkyLight(section, x, y, z, 0);
continue; continue;
} }
switch (value) { switch (value) {
case 0: case 0:
if (opacity != 0) { if (opacity != 0) {
queue.setSkyLight(section, x, y, z, 0);
continue; continue;
} }
break; break;
@ -99,25 +201,26 @@ public class NMSRelighter {
queue.setSkyLight(section, x, y, z, value); queue.setSkyLight(section, x, y, z, value);
} }
} }
for (RelightChunk chunk : chunks) { // Smooth forwards for (RelightSkyEntry chunk : chunks) { // Smooth forwards
if (chunk.smooth) { if (chunk.smooth) {
smooth(chunk, y, true); smoothSkyLight(chunk, y, true);
} }
} }
for (int i = chunks.length - 1; i>= 0; i--) { // Smooth backwards for (int i = chunks.length - 1; i>= 0; i--) { // Smooth backwards
RelightChunk chunk = chunks[i]; RelightSkyEntry chunk = chunks[i];
if (chunk.smooth) { if (chunk.smooth) {
smooth(chunk, y, false); smoothSkyLight(chunk, y, false);
} }
} }
} }
} }
public void smooth(RelightChunk chunk, int y, boolean direction) { public void smoothSkyLight(RelightSkyEntry chunk, int y, boolean direction) {
byte[] mask = chunk.mask; byte[] mask = chunk.mask;
int bx = chunk.x << 4; int bx = chunk.x << 4;
int bz = chunk.z << 4; int bz = chunk.z << 4;
queue.ensureChunkLoaded(chunk.x, chunk.z);
Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z); Object sections = queue.getCachedSections(queue.getWorld(), chunk.x, chunk.z);
if (sections == null) return; if (sections == null) return;
Object section = queue.getCachedSection(sections, y >> 4); Object section = queue.getCachedSection(sections, y >> 4);
@ -158,24 +261,54 @@ public class NMSRelighter {
return true; return true;
} }
private class RelightChunk implements Comparable { 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() {
return MathMan.unpairIntX(coord);
}
public int getZ() {
return MathMan.unpairIntY(coord);
}
}
private class RelightSkyEntry implements Comparable {
public final int x; public final int x;
public final int z; public final int z;
public final byte[] mask; public final byte[] mask;
public final boolean[] fix;
public boolean smooth; public boolean smooth;
public RelightChunk(int x, int z) { public RelightSkyEntry(int x, int z, boolean[] fix) {
this.x = x; this.x = x;
this.z = z; this.z = z;
byte[] array = new byte[256]; byte[] array = new byte[256];
Arrays.fill(array, (byte) 15); Arrays.fill(array, (byte) 15);
this.mask = array; this.mask = array;
if (fix == null) {
this.fix = new boolean[16];
Arrays.fill(this.fix, true);
} else {
this.fix = fix;
}
} }
@Override @Override
public int compareTo(Object o) { public int compareTo(Object o) {
RelightChunk other = (RelightChunk) o; RelightSkyEntry other = (RelightSkyEntry) o;
if (other.x < x) { if (other.x < x) {
return -1; return -1;
} }

View File

@ -1,7 +1,6 @@
package com.boydti.fawe.object; package com.boydti.fawe.object;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.Settings;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BaseBiome;
import java.util.ArrayDeque; import java.util.ArrayDeque;
@ -78,13 +77,6 @@ public abstract class FaweChunk<T> {
parent.setChunk(this); parent.setChunk(this);
} }
/**
* Fix the lighting in this chunk
*/
public void fixLighting() {
parent.fixLighting(this, FaweQueue.RelightMode.values()[Settings.LIGHTING.MODE]);
}
/** /**
* This may return the raw value or constructed depending on the implementation<br> * This may return the raw value or constructed depending on the implementation<br>
* - The first index (i) is the layer (layer = y >> 4) (16 layers)<br> * - The first index (i) is the layer (layer = y >> 4) (16 layers)<br>

View File

@ -3,9 +3,9 @@ package com.boydti.fawe.object;
import com.boydti.fawe.Fawe; import com.boydti.fawe.Fawe;
import com.boydti.fawe.FaweCache; import com.boydti.fawe.FaweCache;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.boydti.fawe.util.MainUtil; import com.boydti.fawe.util.MainUtil;
import com.boydti.fawe.util.MathMan;
import com.boydti.fawe.util.MemUtil; import com.boydti.fawe.util.MemUtil;
import com.boydti.fawe.util.SetQueue; import com.boydti.fawe.util.SetQueue;
import com.boydti.fawe.util.TaskManager; import com.boydti.fawe.util.TaskManager;
@ -43,11 +43,7 @@ public abstract class FaweQueue {
public enum RelightMode { public enum RelightMode {
NONE, NONE,
SHADOWLESS,
MINIMAL,
FULLBRIGHT,
OPTIMAL, OPTIMAL,
FAST,
ALL, ALL,
} }
@ -139,26 +135,7 @@ public abstract class FaweQueue {
public abstract void setChunk(final FaweChunk<?> chunk); public abstract void setChunk(final FaweChunk<?> chunk);
public boolean fixLightingSafe(final FaweChunk<?> chunk, final RelightMode mode) { public abstract File getSaveFolder();
if (Settings.LIGHTING.ASYNC || Fawe.get().isMainThread()) {
try {
if (fixLighting(chunk, mode)) {
return true;
}
if (Fawe.get().isMainThread()) {
return false;
}
} catch (Throwable ignore) {}
}
return TaskManager.IMP.syncWhenFree(new RunnableVal<Boolean>() {
@Override
public void run(Boolean value) {
this.value = fixLighting(chunk, mode);
}
});
}
public abstract void forEachMCA(RunnableVal<File> onEach);
public void forEachBlockInChunk(int cx, int cz, RunnableVal2<Vector, BaseBlock> onEach) { public void forEachBlockInChunk(int cx, int cz, RunnableVal2<Vector, BaseBlock> onEach) {
int bx = cx << 4; int bx = cx << 4;
@ -216,8 +193,6 @@ public abstract class FaweQueue {
} }
} }
public abstract boolean fixLighting(final FaweChunk<?> chunk, RelightMode mode);
public abstract boolean isChunkLoaded(final int x, final int z); public abstract boolean isChunkLoaded(final int x, final int z);
public abstract boolean regenerateChunk(int x, int z); public abstract boolean regenerateChunk(int x, int z);
@ -256,7 +231,7 @@ public abstract class FaweQueue {
// Unload chunks // Unload chunks
} }
public abstract void sendChunk(FaweChunk chunk, RelightMode mode); public abstract void sendChunk(FaweChunk chunk);
/** /**
* This method is called when the server is < 1% available memory * This method is called when the server is < 1% available memory
@ -319,6 +294,22 @@ public abstract class FaweQueue {
} }
} }
public int getBrightness(int x, int y, int z) {
int combined = getCombinedId4Data(x, y, z);
if (combined == 0) {
return 0;
}
BlockMaterial block = BundledBlockData.getInstance().getMaterialById(FaweCache.getId(combined));
if (block == null) {
return 255;
}
return block.getLightValue();
}
public int getOpacityBrightnessPair(int x, int y, int z) {
return MathMan.pair16(Math.min(15, getOpacity(x, y, z)), getBrightness(x, y, z));
}
public int getOpacity(int x, int y, int z) { public int getOpacity(int x, int y, int z) {
int combined = getCombinedId4Data(x, y, z); int combined = getCombinedId4Data(x, y, z);
if (combined == 0) { if (combined == 0) {

View File

@ -100,12 +100,11 @@ public class FaweLocalBlockQueue extends LocalBlockQueue {
@Override @Override
public void refreshChunk(int x, int z) { public void refreshChunk(int x, int z) {
IMP.sendChunk(IMP.getFaweChunk(x, z), FaweQueue.RelightMode.NONE); IMP.sendChunk(IMP.getFaweChunk(x, z));
} }
@Override @Override
public void fixChunkLighting(int x, int z) { public void fixChunkLighting(int x, int z) {
IMP.fixLighting(IMP.getFaweChunk(x, z), FaweQueue.RelightMode.OPTIMAL);
} }
@Override @Override

View File

@ -2,7 +2,6 @@ package com.boydti.fawe.util;
import com.boydti.fawe.object.FaweChunk; import com.boydti.fawe.object.FaweChunk;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.object.RunnableVal;
import com.boydti.fawe.object.RunnableVal2; import com.boydti.fawe.object.RunnableVal2;
import com.boydti.fawe.object.exception.FaweException; import com.boydti.fawe.object.exception.FaweException;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -130,13 +129,8 @@ public class DelegateFaweQueue extends FaweQueue {
} }
@Override @Override
public void forEachMCA(RunnableVal<File> onEach) { public File getSaveFolder() {
parent.forEachMCA(onEach); return parent.getSaveFolder();
}
@Override
public boolean fixLighting(FaweChunk<?> chunk, RelightMode mode) {
return parent.fixLighting(chunk, mode);
} }
@Override @Override
@ -175,8 +169,8 @@ public class DelegateFaweQueue extends FaweQueue {
} }
@Override @Override
public void sendChunk(FaweChunk chunk, RelightMode mode) { public void sendChunk(FaweChunk chunk) {
parent.sendChunk(chunk, mode); parent.sendChunk(chunk);
} }
@Override @Override

View File

@ -43,6 +43,18 @@ public class MathMan {
253, 254, 254, 255 253, 254, 254, 255
}; };
public static short pairByte(int x, int y) {
return (short) ((x << 8) | (y & 0xFF));
}
public static byte unpairShortX(short pair) {
return (byte) (pair >> 8);
}
public static byte unpairShortY(short pair) {
return (byte) pair;
}
public static long pairInt(int x, int y) { public static long pairInt(int x, int y) {
return (((long)x) << 32) | (y & 0xffffffffL); return (((long)x) << 32) | (y & 0xffffffffL);
} }
@ -59,7 +71,7 @@ public class MathMan {
return (int)pair; return (int)pair;
} }
public static byte pair16(byte x, byte y) { public static byte pair16(int x, int y) {
return (byte) (x + (y << 4)); return (byte) (x + (y << 4));
} }

View File

@ -94,8 +94,13 @@ public class WorldWrapper extends LocalWorld {
} }
@Override @Override
public void simulateBlockMine(Vector pt) { public void simulateBlockMine(final Vector pt) {
parent.simulateBlockMine(pt); TaskManager.IMP.sync(new RunnableVal<Object>() {
@Override
public void run(Object value) {
parent.simulateBlockMine(pt);
}
});
} }
@Override @Override

View File

@ -21,15 +21,18 @@ package com.sk89q.worldedit.command;
import com.boydti.fawe.FaweAPI; import com.boydti.fawe.FaweAPI;
import com.boydti.fawe.config.BBC; import com.boydti.fawe.config.BBC;
import com.boydti.fawe.example.NMSMappedFaweQueue;
import com.boydti.fawe.object.FaweLocation; import com.boydti.fawe.object.FaweLocation;
import com.boydti.fawe.object.FawePlayer; import com.boydti.fawe.object.FawePlayer;
import com.boydti.fawe.object.FaweQueue; import com.boydti.fawe.object.FaweQueue;
import com.boydti.fawe.util.SetQueue;
import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.Logging; import com.sk89q.minecraft.util.commands.Logging;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseBlock;
@ -96,7 +99,7 @@ public class RegionCommands {
min = 0, min = 0,
max = 0 max = 0
) )
@CommandPermissions("worldedit.light.get") @CommandPermissions("worldedit.light.fix")
public void fixlighting(Player player, EditSession editSession) throws WorldEditException { public void fixlighting(Player player, EditSession editSession) throws WorldEditException {
FawePlayer fp = FawePlayer.wrap(player); FawePlayer fp = FawePlayer.wrap(player);
final FaweLocation loc = fp.getLocation(); final FaweLocation loc = fp.getLocation();
@ -111,6 +114,75 @@ public class RegionCommands {
BBC.FIX_LIGHTING_SELECTION.send(fp, count); BBC.FIX_LIGHTING_SELECTION.send(fp, count);
} }
@Command(
aliases = { "/removelight", "/removelighting" },
desc = "Removing lighting in a selection",
min = 0,
max = 0
)
@CommandPermissions("worldedit.light.remove")
public void removelighting(Player player, EditSession editSession) {
FawePlayer fp = FawePlayer.wrap(player);
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
Region selection = fp.getSelection();
if (selection == null) {
selection = new CuboidRegion(new Vector(cx - 8, 0, cz - 8).multiply(16), new Vector(cx + 8, 0, cz + 8).multiply(16));
}
int count = FaweAPI.fixLighting(loc.world, selection, FaweQueue.RelightMode.NONE);
BBC.UPDATED_LIGHTING_SELECTION.send(fp, count);
}
@Command(
aliases = { "/setblocklight", "/setlight" },
desc = "Set block lighting in a selection",
min = 1,
max = 1
)
@CommandPermissions("worldedit.light.set")
public void setlighting(Player player, EditSession editSession, @Selection Region region, int value) {
FawePlayer fp = FawePlayer.wrap(player);
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getLocation().world, true, false);
for (Vector pt : region) {
queue.setBlockLight((byte) pt.x, (byte) pt.y, (byte) pt.z, value);
}
int count = 0;
for (Vector2D chunk : region.getChunks()) {
queue.sendChunk(queue.getFaweChunk(chunk.getBlockX(), chunk.getBlockZ()));
count++;
}
BBC.UPDATED_LIGHTING_SELECTION.send(fp, count);
}
@Command(
aliases = { "/setskylight"},
desc = "Set sky lighting in a selection",
min = 1,
max = 1
)
@CommandPermissions("worldedit.light.set")
public void setskylighting(Player player, EditSession editSession, @Selection Region region, int value) {
FawePlayer fp = FawePlayer.wrap(player);
final FaweLocation loc = fp.getLocation();
final int cx = loc.x >> 4;
final int cz = loc.z >> 4;
final NMSMappedFaweQueue queue = (NMSMappedFaweQueue) SetQueue.IMP.getNewQueue(fp.getLocation().world, true, false);
for (Vector pt : region) {
queue.setSkyLight((byte) pt.x, (byte) pt.y, (byte) pt.z, value);
}
int count = 0;
for (Vector2D chunk : region.getChunks()) {
queue.sendChunk(queue.getFaweChunk(chunk.getBlockX(), chunk.getBlockZ()));
count++;
}
BBC.UPDATED_LIGHTING_SELECTION.send(fp, count);
}
@Command( @Command(
aliases = { "/line" }, aliases = { "/line" },
usage = "<block> [thickness]", usage = "<block> [thickness]",

View File

@ -15,6 +15,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -46,6 +47,7 @@ import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.IntHashMap; import net.minecraft.util.IntHashMap;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.BlockStateContainer;
@ -57,7 +59,7 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], BlockStateContainer> { public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
private static Method methodFromNative; private static Method methodFromNative;
private static Method methodToNative; private static Method methodToNative;
@ -185,14 +187,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public BlockStateContainer getCachedSection(ExtendedBlockStorage[] chunk, int cy) { public ExtendedBlockStorage getCachedSection(ExtendedBlockStorage[] chunk, int cy) {
ExtendedBlockStorage value = chunk[cy]; return chunk[cy];
return value == null ? null : value.getData();
} }
@Override @Override
public int getCombinedId4Data(BlockStateContainer ls, int x, int y, int z) { public int getCombinedId4Data(ExtendedBlockStorage section, int x, int y, int z) {
IBlockState ibd = lastSection.get(x & 15, y & 15, z & 15); IBlockState ibd = section.getData().get(x & 15, y & 15, z & 15);
Block block = ibd.getBlock(); Block block = ibd.getBlock();
int id = Block.getIdFromBlock(block); int id = Block.getIdFromBlock(block);
if (FaweCache.hasData(id)) { if (FaweCache.hasData(id)) {
@ -502,7 +503,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }
@ -618,36 +618,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
return !nmsWorld.provider.getHasNoSky(); return !nmsWorld.provider.getHasNoSky();
} }
@Override
public boolean initLighting(Chunk nmsChunk, ExtendedBlockStorage[] sections, RelightMode mode) {
if (mode == RelightMode.ALL) {
nmsChunk.generateSkylightMap();
} else {
int i = nmsChunk.getTopFilledSegment();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = nmsChunk.getBlockLightOpacity(new BlockPos(x, y, z));
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ExtendedBlockStorage section = sections[y >> 4];
if (section != null) {
section.setExtSkylightValue(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override @Override
public void setFullbright(ExtendedBlockStorage[] sections) { public void setFullbright(ExtendedBlockStorage[] sections) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
@ -659,24 +629,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
@Override
public int getSkyLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.getExtSkylightValue(x, y & 15, z);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.getExtBlocklightValue(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.setPos(x, y, z); pos.setPos(x, y, z);
@ -697,32 +649,60 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkylightArray().set(x & 15, y & 15, z & 15, value); section.getSkylightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getBlocklightArray().set(x & 15, y & 15, z & 15, value); section.getBlocklightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override
public int getSkyLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtSkylightValue(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtBlocklightValue(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return ibd.getLightOpacity();
}
@Override
public int getBrightness(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return ibd.getLightValue();
}
@Override
public int getOpacityBrightnessPair(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return MathMan.pair16(ibd.getLightOpacity(), ibd.getLightValue());
}
@Override
public void relightBlock(int x, int y, int z) {
pos.setPos(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.setPos(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.SKY, pos);
}
@Override
public File getSaveFolder() {
return new File(((WorldServer) getWorld()).getChunkSaveLocation(), "region");
}
} }

View File

@ -16,6 +16,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -27,6 +28,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityTracker; import net.minecraft.entity.EntityTracker;
@ -43,6 +45,7 @@ import net.minecraft.util.IntHashMap;
import net.minecraft.util.LongHashMap; import net.minecraft.util.LongHashMap;
import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.ChunkPosition; import net.minecraft.world.ChunkPosition;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
@ -506,7 +509,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }
@ -612,36 +614,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
return !nmsWorld.provider.hasNoSky; return !nmsWorld.provider.hasNoSky;
} }
@Override
public boolean initLighting(Chunk nmsChunk, ExtendedBlockStorage[] sections, RelightMode mode) {
if (mode == RelightMode.ALL) {
nmsChunk.generateSkylightMap();
} else {
int i = nmsChunk.getTopFilledSegment();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = nmsChunk.func_150808_b(x, y, z);
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ExtendedBlockStorage section = sections[y >> 4];
if (section != null) {
section.setExtSkylightValue(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override @Override
public void setFullbright(ExtendedBlockStorage[] sections) { public void setFullbright(ExtendedBlockStorage[] sections) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
@ -653,24 +625,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
@Override
public int getSkyLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.getExtSkylightValue(x, y & 15, z);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.getExtBlocklightValue(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
nmsWorld.func_147451_t(x, y, z); nmsWorld.func_147451_t(x, y, z);
@ -689,32 +643,73 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkylightArray().set(x & 15, y & 15, z & 15, value); section.getSkylightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getBlocklightArray().set(x & 15, y & 15, z & 15, value); section.getBlocklightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override
public int getSkyLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtSkylightValue(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtBlocklightValue(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return block.getLightOpacity();
}
@Override
public int getBrightness(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return block.getLightValue();
}
@Override
public int getOpacityBrightnessPair(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return MathMan.pair16(block.getLightOpacity(), block.getLightValue());
}
@Override
public boolean hasBlock(ExtendedBlockStorage section, int x, int y, int z) {
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
return section.getBlockLSBArray()[i] != 0;
}
@Override
public void relightBlock(int x, int y, int z) {
nmsWorld.updateLightByType(EnumSkyBlock.Block, x, y, z);
}
@Override
public void relightSky(int x, int y, int z) {
nmsWorld.updateLightByType(EnumSkyBlock.Sky, x, y, z);
}
@Override
public File getSaveFolder() {
return new File(((WorldServer) getWorld()).getChunkSaveLocation(), "region");
}
} }

View File

@ -15,6 +15,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -25,6 +26,7 @@ import java.util.Iterator;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import net.minecraft.block.Block;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityTracker; import net.minecraft.entity.EntityTracker;
@ -41,6 +43,7 @@ import net.minecraft.util.BlockPos;
import net.minecraft.util.ClassInheritanceMultiMap; import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.IntHashMap; import net.minecraft.util.IntHashMap;
import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
@ -50,7 +53,7 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], char[]> { public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
private static Method methodFromNative; private static Method methodFromNative;
private static Method methodToNative; private static Method methodToNative;
@ -155,14 +158,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public char[] getCachedSection(ExtendedBlockStorage[] chunk, int cy) { public ExtendedBlockStorage getCachedSection(ExtendedBlockStorage[] chunk, int cy) {
ExtendedBlockStorage value = chunk[cy]; return chunk[cy];
return value == null ? null : value.getData();
} }
@Override @Override
public int getCombinedId4Data(char[] ls, int x, int y, int z) { public int getCombinedId4Data(ExtendedBlockStorage ls, int x, int y, int z) {
return ls[FaweCache.CACHE_J[y][x & 15][z & 15]]; return ls.getData()[FaweCache.CACHE_J[y][x & 15][z & 15]];
} }
@Override @Override
@ -447,7 +449,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }
@ -574,36 +575,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
return !nmsWorld.provider.getHasNoSky(); return !nmsWorld.provider.getHasNoSky();
} }
@Override
public boolean initLighting(Chunk nmsChunk, ExtendedBlockStorage[] sections, RelightMode mode) {
if (mode == RelightMode.ALL) {
nmsChunk.generateSkylightMap();
} else {
int i = nmsChunk.getTopFilledSegment();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = nmsChunk.getBlockLightOpacity(new BlockPos(x, y, z));
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ExtendedBlockStorage section = sections[y >> 4];
if (section != null) {
section.setExtSkylightValue(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override @Override
public void setFullbright(ExtendedBlockStorage[] sections) { public void setFullbright(ExtendedBlockStorage[] sections) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
@ -615,24 +586,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
@Override
public int getSkyLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.getExtSkylightValue(x, y & 15, z);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.getExtBlocklightValue(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.set(x, y, z); pos.set(x, y, z);
@ -652,32 +605,75 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkylightArray().set(x & 15, y & 15, z & 15, value); section.getSkylightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getBlocklightArray().set(x & 15, y & 15, z & 15, value); section.getBlocklightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override
public int getSkyLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtSkylightValue(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtBlocklightValue(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return block.getLightOpacity();
}
@Override
public int getBrightness(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return block.getLightValue();
}
@Override
public int getOpacityBrightnessPair(ExtendedBlockStorage section, int x, int y, int z) {
int combined = getCombinedId4Data(section, x, y, z);
if (combined == 0) {
return 0;
}
Block block = Block.getBlockById(FaweCache.getId(combined));
return MathMan.pair16(block.getLightOpacity(), block.getLightValue());
}
@Override
public boolean hasBlock(ExtendedBlockStorage section, int x, int y, int z) {
int i = FaweCache.CACHE_J[y & 15][x & 15][z & 15];
return section.getData()[i] != 0;
}
@Override
public void relightBlock(int x, int y, int z) {
pos.set(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.set(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.SKY, pos);
}
@Override
public File getSaveFolder() {
return new File(((WorldServer) getWorld()).getChunkSaveLocation(), "region");
}
} }

View File

@ -15,6 +15,7 @@ import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag; import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.StringTag; import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag; import com.sk89q.jnbt.Tag;
import java.io.File;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
@ -46,6 +47,7 @@ import net.minecraft.util.ClassInheritanceMultiMap;
import net.minecraft.util.IntHashMap; import net.minecraft.util.IntHashMap;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.EnumSkyBlock;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.chunk.BlockStateContainer; import net.minecraft.world.chunk.BlockStateContainer;
@ -57,7 +59,7 @@ import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraftforge.common.DimensionManager; import net.minecraftforge.common.DimensionManager;
public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], BlockStateContainer> { public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlockStorage[], ExtendedBlockStorage> {
private static Method methodFromNative; private static Method methodFromNative;
private static Method methodToNative; private static Method methodToNative;
@ -185,14 +187,13 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public BlockStateContainer getCachedSection(ExtendedBlockStorage[] chunk, int cy) { public ExtendedBlockStorage getCachedSection(ExtendedBlockStorage[] chunk, int cy) {
ExtendedBlockStorage value = chunk[cy]; return chunk[cy];
return value == null ? null : value.getData();
} }
@Override @Override
public int getCombinedId4Data(BlockStateContainer ls, int x, int y, int z) { public int getCombinedId4Data(ExtendedBlockStorage section, int x, int y, int z) {
IBlockState ibd = lastSection.get(x & 15, y & 15, z & 15); IBlockState ibd = section.getData().get(x & 15, y & 15, z & 15);
Block block = ibd.getBlock(); Block block = ibd.getBlock();
int id = Block.getIdFromBlock(block); int id = Block.getIdFromBlock(block);
if (FaweCache.hasData(id)) { if (FaweCache.hasData(id)) {
@ -502,7 +503,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
} }
sendChunk(fs, null);
return true; return true;
} }
@ -618,36 +618,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
return !nmsWorld.provider.getHasNoSky(); return !nmsWorld.provider.getHasNoSky();
} }
@Override
public boolean initLighting(Chunk nmsChunk, ExtendedBlockStorage[] sections, RelightMode mode) {
if (mode == RelightMode.ALL) {
nmsChunk.generateSkylightMap();
} else {
int i = nmsChunk.getTopFilledSegment();
for (int x = 0; x < 16; ++x) {
for (int z = 0; z < 16; ++z) {
int l = 15;
int y = i + 16 - 1;
do {
int opacity = nmsChunk.getBlockLightOpacity(new BlockPos(x, y, z));
if (opacity == 0 && l != 15) {
opacity = 1;
}
l -= opacity;
if (l > 0) {
ExtendedBlockStorage section = sections[y >> 4];
if (section != null) {
section.setExtSkylightValue(x, y & 15, z, l);
}
}
--y;
} while (y > 0 && l > 0);
}
}
}
return true;
}
@Override @Override
public void setFullbright(ExtendedBlockStorage[] sections) { public void setFullbright(ExtendedBlockStorage[] sections) {
for (int i = 0; i < sections.length; i++) { for (int i = 0; i < sections.length; i++) {
@ -659,24 +629,6 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
} }
@Override
public int getSkyLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 15;
}
return section.getExtSkylightValue(x, y & 15, z);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage[] sections, int x, int y, int z) {
ExtendedBlockStorage section = sections[FaweCache.CACHE_I[y][x][z]];
if (section == null) {
return 0;
}
return section.getExtBlocklightValue(x, y & 15, z);
}
@Override @Override
public void relight(int x, int y, int z) { public void relight(int x, int y, int z) {
pos.setPos(x, y, z); pos.setPos(x, y, z);
@ -696,32 +648,60 @@ public class ForgeQueue_All extends NMSMappedFaweQueue<World, Chunk, ExtendedBlo
} }
@Override @Override
public void setSkyLight(int x, int y, int z, int value) { public void setSkyLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getSkylightArray().set(x & 15, y & 15, z & 15, value); section.getSkylightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override @Override
public void setBlockLight(int x, int y, int z, int value) { public void setBlockLight(ExtendedBlockStorage section, int x, int y, int z, int value) {
int cx = x >> 4;
int cz = z >> 4;
if (!ensureChunkLoaded(cx, cz)) {
return;
}
ExtendedBlockStorage[] sections = getCachedSections(getWorld(), cx, cz);
ExtendedBlockStorage section = sections[y >> 4];
if (section == null) {
return;
}
section.getBlocklightArray().set(x & 15, y & 15, z & 15, value); section.getBlocklightArray().set(x & 15, y & 15, z & 15, value);
} }
@Override
public int getSkyLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtSkylightValue(x & 15, y & 15, z & 15);
}
@Override
public int getEmmittedLight(ExtendedBlockStorage section, int x, int y, int z) {
return section.getExtBlocklightValue(x & 15, y & 15, z & 15);
}
@Override
public int getOpacity(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return ibd.getLightOpacity();
}
@Override
public int getBrightness(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return ibd.getLightValue();
}
@Override
public int getOpacityBrightnessPair(ExtendedBlockStorage section, int x, int y, int z) {
BlockStateContainer dataPalette = section.getData();
IBlockState ibd = dataPalette.get(x & 15, y & 15, z & 15);
return MathMan.pair16(ibd.getLightOpacity(), ibd.getLightValue());
}
@Override
public void relightBlock(int x, int y, int z) {
pos.setPos(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.BLOCK, pos);
}
@Override
public void relightSky(int x, int y, int z) {
pos.setPos(x, y, z);
nmsWorld.checkLightFor(EnumSkyBlock.SKY, pos);
}
@Override
public File getSaveFolder() {
return new File(((WorldServer) getWorld()).getChunkSaveLocation(), "region");
}
} }