mirror of
https://github.com/plexusorg/Plex-FAWE.git
synced 2025-01-09 17:27:38 +00:00
Begin working on improved lighting to better match 1.14's "new" light… (#611)
* Begin working on improved lighting to better match 1.14's "new" lighting engine I guess the "new" lighting engine is somewhat old now lol Also implement the remove first stuff to fixlight * And then make it work
This commit is contained in:
parent
d00899e177
commit
4243e8e86b
@ -381,8 +381,12 @@ public class FaweAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mode != RelightMode.NONE) {
|
if (mode != RelightMode.NONE) {
|
||||||
|
if (Settings.IMP.LIGHTING.REMOVE_FIRST) {
|
||||||
|
relighter.removeAndRelight(true);
|
||||||
|
} else {
|
||||||
relighter.fixSkyLighting();
|
relighter.fixSkyLighting();
|
||||||
relighter.fixBlockLighting();
|
relighter.fixBlockLighting();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
relighter.removeLighting();
|
relighter.removeLighting();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,13 @@ import com.boydti.fawe.object.collection.BlockVectorSet;
|
|||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.sk89q.worldedit.math.MutableBlockVector3;
|
import com.sk89q.worldedit.math.MutableBlockVector3;
|
||||||
|
import com.sk89q.worldedit.registry.state.DirectionalProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.EnumProperty;
|
||||||
|
import com.sk89q.worldedit.registry.state.Property;
|
||||||
|
import com.sk89q.worldedit.util.Direction;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
import com.sk89q.worldedit.world.registry.BlockMaterial;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
@ -25,22 +32,29 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class NMSRelighter implements Relighter {
|
public class NMSRelighter implements Relighter {
|
||||||
private final IQueueExtent<IQueueChunk> queue;
|
private static final int DISPATCH_SIZE = 64;
|
||||||
|
private static final DirectionalProperty stairDirection;
|
||||||
|
private static final EnumProperty stairHalf;
|
||||||
|
private static final EnumProperty stairShape;
|
||||||
|
private static final EnumProperty slabHalf;
|
||||||
|
|
||||||
|
static {
|
||||||
|
stairDirection = (DirectionalProperty) (Property<?>) BlockTypes.SANDSTONE_STAIRS.getProperty("facing");
|
||||||
|
stairHalf = (EnumProperty) (Property<?>) BlockTypes.SANDSTONE_STAIRS.getProperty("half");
|
||||||
|
stairShape = (EnumProperty) (Property<?>) BlockTypes.SANDSTONE_STAIRS.getProperty("shape");
|
||||||
|
slabHalf = (EnumProperty) (Property<?>) BlockTypes.SANDSTONE_SLAB.getProperty("type");
|
||||||
|
}
|
||||||
|
|
||||||
|
public final MutableBlockVector3 mutableBlockPos = new MutableBlockVector3(0, 0, 0);
|
||||||
|
private final IQueueExtent<IQueueChunk> queue;
|
||||||
private final Map<Long, RelightSkyEntry> skyToRelight;
|
private final Map<Long, RelightSkyEntry> skyToRelight;
|
||||||
private final Object present = new Object();
|
private final Object present = new Object();
|
||||||
private final Map<Long, Integer> chunksToSend;
|
private final Map<Long, Integer> chunksToSend;
|
||||||
private final ConcurrentLinkedQueue<RelightSkyEntry> extentdSkyToRelight = new ConcurrentLinkedQueue<>();
|
private final ConcurrentLinkedQueue<RelightSkyEntry> extentdSkyToRelight = new ConcurrentLinkedQueue<>();
|
||||||
|
private final Map<Long, long[][][] /* z y x */> lightQueue;
|
||||||
private final Map<Long, long[][][] /* z y x */ > lightQueue;
|
|
||||||
private final AtomicBoolean lightLock = new AtomicBoolean(false);
|
private final AtomicBoolean lightLock = new AtomicBoolean(false);
|
||||||
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
private final ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
||||||
|
|
||||||
private final int maxY;
|
private final int maxY;
|
||||||
|
|
||||||
public final MutableBlockVector3 mutableBlockPos = new MutableBlockVector3(0, 0, 0);
|
|
||||||
|
|
||||||
private static final int DISPATCH_SIZE = 64;
|
|
||||||
private boolean removeFirst;
|
private boolean removeFirst;
|
||||||
|
|
||||||
public NMSRelighter(IQueueExtent<IQueueChunk> queue) {
|
public NMSRelighter(IQueueExtent<IQueueChunk> queue) {
|
||||||
@ -52,13 +66,11 @@ public class NMSRelighter implements Relighter {
|
|||||||
this.maxY = queue.getMaxY();
|
this.maxY = queue.getMaxY();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public boolean isEmpty() {
|
||||||
public boolean isEmpty() {
|
|
||||||
return skyToRelight.isEmpty() && lightQueue.isEmpty() && extentdSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
return skyToRelight.isEmpty() && lightQueue.isEmpty() && extentdSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public synchronized void removeAndRelight(boolean sky) {
|
||||||
public synchronized void removeAndRelight(boolean sky) {
|
|
||||||
removeFirst = true;
|
removeFirst = true;
|
||||||
fixLightingSafe(sky);
|
fixLightingSafe(sky);
|
||||||
removeFirst = false;
|
removeFirst = false;
|
||||||
@ -147,7 +159,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
long pair = entry.getKey();
|
long pair = entry.getKey();
|
||||||
Integer existing = chunksToSend.get(pair);
|
Integer existing = chunksToSend.get(pair);
|
||||||
chunksToSend.put(pair, chunk.bitmask | (existing != null ? existing : 0));
|
chunksToSend.put(pair, chunk.bitmask | (existing != null ? existing : 0));
|
||||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(queue, chunk.x, chunk.z);
|
iChunk.init(queue, chunk.x, chunk.z);
|
||||||
}
|
}
|
||||||
@ -168,6 +180,9 @@ public class NMSRelighter implements Relighter {
|
|||||||
Map<MutableBlockVector3, Object> visited = new HashMap<>(32);
|
Map<MutableBlockVector3, Object> visited = new HashMap<>(32);
|
||||||
Map<MutableBlockVector3, Object> removalVisited = new HashMap<>(32);
|
Map<MutableBlockVector3, Object> removalVisited = new HashMap<>(32);
|
||||||
|
|
||||||
|
// Make sure BlockTypes is initialised so we can check block characteristics later if needed
|
||||||
|
BlockTypes.STONE.getMaterial();
|
||||||
|
|
||||||
Iterator<Map.Entry<Long, long[][][]>> iter = map.entrySet().iterator();
|
Iterator<Map.Entry<Long, long[][][]>> iter = map.entrySet().iterator();
|
||||||
while (iter.hasNext() && size-- > 0) {
|
while (iter.hasNext() && size-- > 0) {
|
||||||
Map.Entry<Long, long[][][]> entry = iter.next();
|
Map.Entry<Long, long[][][]> entry = iter.next();
|
||||||
@ -177,16 +192,20 @@ public class NMSRelighter implements Relighter {
|
|||||||
int chunkZ = MathMan.unpairIntY(index);
|
int chunkZ = MathMan.unpairIntY(index);
|
||||||
int bx = chunkX << 4;
|
int bx = chunkX << 4;
|
||||||
int bz = chunkZ << 4;
|
int bz = chunkZ << 4;
|
||||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunkX, chunkZ);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunkX, chunkZ);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(queue, chunkX, chunkZ);
|
iChunk.init(queue, chunkX, chunkZ);
|
||||||
}
|
}
|
||||||
for (int lz = 0; lz < blocks.length; lz++) {
|
for (int lz = 0; lz < blocks.length; lz++) {
|
||||||
long[][] m1 = blocks[lz];
|
long[][] m1 = blocks[lz];
|
||||||
if (m1 == null) continue;
|
if (m1 == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int lx = 0; lx < m1.length; lx++) {
|
for (int lx = 0; lx < m1.length; lx++) {
|
||||||
long[] m2 = m1[lx];
|
long[] m2 = m1[lx];
|
||||||
if (m2 == null) continue;
|
if (m2 == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for (int i = 0; i < m2.length; i++) {
|
for (int i = 0; i < m2.length; i++) {
|
||||||
int yStart = i << 6;
|
int yStart = i << 6;
|
||||||
long value = m2[i];
|
long value = m2[i];
|
||||||
@ -203,7 +222,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
MutableBlockVector3 node = new MutableBlockVector3(x, y, z);
|
MutableBlockVector3 node = new MutableBlockVector3(x, y, z);
|
||||||
if (newLevel < oldLevel) {
|
if (newLevel < oldLevel) {
|
||||||
removalVisited.put(node, present);
|
removalVisited.put(node, present);
|
||||||
lightRemovalQueue.add(new Object[]{node, oldLevel});
|
lightRemovalQueue.add(new Object[] {node, oldLevel});
|
||||||
} else {
|
} else {
|
||||||
visited.put(node, present);
|
visited.put(node, present);
|
||||||
lightPropagationQueue.add(node);
|
lightPropagationQueue.add(node);
|
||||||
@ -223,43 +242,458 @@ public class NMSRelighter implements Relighter {
|
|||||||
MutableBlockVector3 node = (MutableBlockVector3) val[0];
|
MutableBlockVector3 node = (MutableBlockVector3) val[0];
|
||||||
int lightLevel = (int) val[1];
|
int lightLevel = (int) val[1];
|
||||||
|
|
||||||
this.computeRemoveBlockLight(node.getX() - 1, node.getY(), node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
this.computeRemoveBlockLight(node.getX() - 1, node.getY(), node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
this.computeRemoveBlockLight(node.getX() + 1, node.getY(), node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
removalVisited, visited);
|
||||||
|
this.computeRemoveBlockLight(node.getX() + 1, node.getY(), node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
|
removalVisited, visited);
|
||||||
if (node.getY() > 0) {
|
if (node.getY() > 0) {
|
||||||
this.computeRemoveBlockLight(node.getX(), node.getY() - 1, node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
this.computeRemoveBlockLight(node.getX(), node.getY() - 1, node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
|
removalVisited, visited);
|
||||||
}
|
}
|
||||||
if (node.getY() < 255) {
|
if (node.getY() < 255) {
|
||||||
this.computeRemoveBlockLight(node.getX(), node.getY() + 1, node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
this.computeRemoveBlockLight(node.getX(), node.getY() + 1, node.getZ(), lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
|
removalVisited, visited);
|
||||||
}
|
}
|
||||||
this.computeRemoveBlockLight(node.getX(), node.getY(), node.getZ() - 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
this.computeRemoveBlockLight(node.getX(), node.getY(), node.getZ() - 1, lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
this.computeRemoveBlockLight(node.getX(), node.getY(), node.getZ() + 1, lightLevel, lightRemovalQueue, lightPropagationQueue, removalVisited, visited);
|
removalVisited, visited);
|
||||||
|
this.computeRemoveBlockLight(node.getX(), node.getY(), node.getZ() + 1, lightLevel, lightRemovalQueue, lightPropagationQueue,
|
||||||
|
removalVisited, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!lightPropagationQueue.isEmpty()) {
|
while (!lightPropagationQueue.isEmpty()) {
|
||||||
MutableBlockVector3 node = lightPropagationQueue.poll();
|
MutableBlockVector3 node = lightPropagationQueue.poll();
|
||||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(node.getX() >> 4, node.getZ() >> 4);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(node.getX() >> 4, node.getZ() >> 4);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(queue, node.getX() >> 4, node.getZ() >> 4);
|
iChunk.init(queue, node.getX() >> 4, node.getZ() >> 4);
|
||||||
}
|
}
|
||||||
int lightLevel = iChunk.getEmmittedLight(node.getX() & 15, node.getY(), node.getZ() & 15);
|
int lightLevel = iChunk.getEmmittedLight(node.getX() & 15, node.getY(), node.getZ() & 15);
|
||||||
if (lightLevel > 1) {
|
BlockState state = this.queue.getBlock(node.getX(), node.getY(), node.getZ());
|
||||||
this.computeSpreadBlockLight(node.getX() - 1, node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited);
|
String id = state.getBlockType().getId().toLowerCase();
|
||||||
this.computeSpreadBlockLight(node.getX() + 1, node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited);
|
if (lightLevel <= 1) {
|
||||||
if (node.getY() > 0) {
|
continue;
|
||||||
this.computeSpreadBlockLight(node.getX(), node.getY() - 1, node.getZ(), lightLevel, lightPropagationQueue, visited);
|
|
||||||
}
|
}
|
||||||
if (node.getY() < 255) {
|
if (id.contains("slab")) {
|
||||||
this.computeSpreadBlockLight(node.getX(), node.getY() + 1, node.getZ(), lightLevel, lightPropagationQueue, visited);
|
boolean top = state.getState(slabHalf).equalsIgnoreCase("top");
|
||||||
}
|
computeSlab(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited, top);
|
||||||
this.computeSpreadBlockLight(node.getX(), node.getY(), node.getZ() - 1, lightLevel, lightPropagationQueue, visited);
|
} else if (id.contains("stair")) {
|
||||||
this.computeSpreadBlockLight(node.getX(), node.getY(), node.getZ() + 1, lightLevel, lightPropagationQueue, visited);
|
boolean top = state.getState(stairHalf).equalsIgnoreCase("top");
|
||||||
|
Direction direction = getStairDir(state);
|
||||||
|
String shape = getStairShape(state);
|
||||||
|
computeStair(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited, top, direction, shape);
|
||||||
|
} else {
|
||||||
|
computeNormal(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeRemoveBlockLight(int x, int y, int z, int currentLight, Queue<Object[]> queue, Queue<MutableBlockVector3> spreadQueue, Map<MutableBlockVector3, Object> visited,
|
private void computeStair(int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
int currentLight,
|
||||||
|
Queue<MutableBlockVector3> queue,
|
||||||
|
Map<MutableBlockVector3, Object> visited,
|
||||||
|
boolean top,
|
||||||
|
Direction direction,
|
||||||
|
String shape) {
|
||||||
|
east:
|
||||||
|
{
|
||||||
|
// Block East
|
||||||
|
if (direction != Direction.WEST && !((direction == Direction.NORTH && !shape.equals("inner_left")) || (direction == Direction.SOUTH
|
||||||
|
&& !shape.equals("inner_right")) || (direction == Direction.EAST && shape.contains("outer")))) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
BlockState state = this.queue.getBlock(x + 1, y, z);
|
||||||
|
if (!(checkStairEast(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited);
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
Direction otherDir = getStairDir(state);
|
||||||
|
String otherShape = getStairShape(state);
|
||||||
|
boolean b1 =
|
||||||
|
(otherDir == Direction.NORTH && !otherShape.equals("outer_right")) || (otherDir == Direction.EAST && otherShape.equals("inner_left"));
|
||||||
|
boolean b2 =
|
||||||
|
(otherDir == Direction.SOUTH && !otherShape.equals("outer_left")) || (otherDir == Direction.EAST && otherShape.equals("inner_right"));
|
||||||
|
switch (direction) {
|
||||||
|
case EAST:
|
||||||
|
if (shape.equals("outer_right") && b1) {
|
||||||
|
break east;
|
||||||
|
} else if (shape.equals("outer_left") && b2) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
if (shape.equals("straight") || shape.contains("outer")) {
|
||||||
|
break;
|
||||||
|
} else if (shape.equals("inner_left") && b1) {
|
||||||
|
break east;
|
||||||
|
} else if (shape.equals("inner_right") && b2) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
if (shape.equals("inner_left") || b1 || (otherDir == Direction.SOUTH && otherShape.equals("inner_right"))) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
if (shape.equals("inner_right") || b2 || (otherDir == Direction.NORTH && otherShape.equals("inner_left"))) {
|
||||||
|
break east;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
west:
|
||||||
|
{
|
||||||
|
// Block West
|
||||||
|
if (direction != Direction.EAST && !((direction == Direction.SOUTH && !shape.equals("inner_left")) || (direction == Direction.NORTH
|
||||||
|
&& !shape.equals("inner_right")) || (direction == Direction.WEST && shape.contains("outer")))) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
BlockState state = this.queue.getBlock(x - 1, y, z);
|
||||||
|
if (!(checkStairWest(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited);
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
Direction otherDir = getStairDir(state);
|
||||||
|
String otherShape = getStairShape(state);
|
||||||
|
boolean b1 =
|
||||||
|
(otherDir == Direction.SOUTH && !otherShape.equals("outer_right")) || (otherDir == Direction.WEST && otherShape.equals("inner_left"));
|
||||||
|
boolean b2 =
|
||||||
|
(otherDir == Direction.NORTH && !otherShape.equals("outer_left")) || (otherDir == Direction.WEST && otherShape.equals("inner_right"));
|
||||||
|
switch (direction) {
|
||||||
|
case WEST:
|
||||||
|
if (shape.equals("outer_right") && b1) {
|
||||||
|
break west;
|
||||||
|
} else if (shape.equals("outer_left") && b2) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
if (shape.equals("straight") || shape.contains("outer")) {
|
||||||
|
break;
|
||||||
|
} else if (shape.equals("inner_left") && b1) {
|
||||||
|
break west;
|
||||||
|
} else if (shape.equals("inner_right") && b2) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
if (shape.equals("inner_left") || b1 || (otherDir == Direction.NORTH && otherShape.equals("inner_right"))) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
if (shape.equals("inner_right") || b2 || (otherDir == Direction.SOUTH && otherShape.equals("inner_left"))) {
|
||||||
|
break west;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
south:
|
||||||
|
{
|
||||||
|
// Block South
|
||||||
|
if (direction != Direction.NORTH && !((direction == Direction.WEST && !shape.equals("inner_left")) || (direction == Direction.EAST
|
||||||
|
&& !shape.equals("inner_right")) || (direction == Direction.SOUTH && shape.contains("outer")))) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z + 1);
|
||||||
|
if (!(checkStairSouth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited);
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
Direction otherDir = getStairDir(state);
|
||||||
|
String otherShape = getStairShape(state);
|
||||||
|
boolean b1 =
|
||||||
|
(otherDir == Direction.EAST && !otherShape.equals("outer_right")) || (otherDir == Direction.SOUTH && otherShape.equals("inner_left"));
|
||||||
|
boolean b2 =
|
||||||
|
(otherDir == Direction.WEST && !otherShape.equals("outer_left")) || (otherDir == Direction.SOUTH && otherShape.equals("inner_right"));
|
||||||
|
switch (direction) {
|
||||||
|
case SOUTH:
|
||||||
|
if (shape.equals("outer_right") && b1) {
|
||||||
|
break south;
|
||||||
|
} else if (shape.equals("outer_left") && b2) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NORTH:
|
||||||
|
if (shape.equals("straight") || shape.contains("outer")) {
|
||||||
|
break;
|
||||||
|
} else if (shape.equals("inner_left") && b1) {
|
||||||
|
break south;
|
||||||
|
} else if (shape.equals("inner_right") && b2) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
if (shape.equals("inner_left") || b1 || (otherDir == Direction.WEST && otherShape.equals("inner_right"))) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
if (shape.equals("inner_right") || b2 || (otherDir == Direction.EAST && otherShape.equals("inner_left"))) {
|
||||||
|
break south;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
north:
|
||||||
|
{
|
||||||
|
// Block North
|
||||||
|
if (direction != Direction.SOUTH && !((direction == Direction.EAST && !shape.equals("inner_left")) || (direction == Direction.WEST
|
||||||
|
&& !shape.equals("inner_right")) || (direction == Direction.NORTH && shape.contains("outer")))) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z - 1);
|
||||||
|
if (!(checkStairNorth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom"))) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited);
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
Direction otherDir = getStairDir(state);
|
||||||
|
String otherShape = getStairShape(state);
|
||||||
|
boolean b1 =
|
||||||
|
(otherDir == Direction.WEST && !otherShape.equals("outer_right")) || (otherDir == Direction.NORTH && otherShape.equals("inner_left"));
|
||||||
|
boolean b2 =
|
||||||
|
(otherDir == Direction.EAST && !otherShape.equals("outer_left")) || (otherDir == Direction.NORTH && otherShape.equals("inner_right"));
|
||||||
|
switch (direction) {
|
||||||
|
case NORTH:
|
||||||
|
if (shape.equals("outer_right") && b1) {
|
||||||
|
break north;
|
||||||
|
} else if (shape.equals("outer_left") && b2) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SOUTH:
|
||||||
|
if (shape.equals("straight") || shape.contains("outer")) {
|
||||||
|
break;
|
||||||
|
} else if (shape.equals("inner_left") && b1) {
|
||||||
|
break north;
|
||||||
|
} else if (shape.equals("inner_right") && b2) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EAST:
|
||||||
|
if (shape.equals("inner_left") || b1 || (otherDir == Direction.EAST && otherShape.equals("inner_right"))) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case WEST:
|
||||||
|
if (shape.equals("inner_right") || b2 || (otherDir == Direction.WEST && otherShape.equals("inner_left"))) {
|
||||||
|
break north;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
computeUpDown(x, y, z, currentLight, queue, visited, top);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeSlab(int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
int currentLight,
|
||||||
|
Queue<MutableBlockVector3> queue,
|
||||||
|
Map<MutableBlockVector3, Object> visited,
|
||||||
|
boolean top) {
|
||||||
|
{
|
||||||
|
// Block East
|
||||||
|
BlockState state = this.queue.getBlock(x + 1, y, z);
|
||||||
|
if (checkStairEast(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom")) {
|
||||||
|
this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block West
|
||||||
|
BlockState state = this.queue.getBlock(x - 1, y, z);
|
||||||
|
if (checkStairWest(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom")) {
|
||||||
|
this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block South
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z + 1);
|
||||||
|
if (checkStairSouth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom")) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block North
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z - 1);
|
||||||
|
if (checkStairNorth(state) && isStairOrTrueTop(state, top) && isSlabOrTrueValue(state, top ? "top" : "bottom")) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
computeUpDown(x, y, z, currentLight, queue, visited, top);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeUpDown(int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
int currentLight,
|
||||||
|
Queue<MutableBlockVector3> queue,
|
||||||
|
Map<MutableBlockVector3, Object> visited,
|
||||||
|
boolean top) {
|
||||||
|
BlockState state = this.queue.getBlock(x, y - 1, z);
|
||||||
|
if (y > 0 && top && isSlabOrTrueValue(state, "bottom") && isStairOrTrueTop(state, false)) {
|
||||||
|
this.computeSpreadBlockLight(x, y - 1, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
state = this.queue.getBlock(x, y + 1, z);
|
||||||
|
if (y < 255 && !top && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, true)) {
|
||||||
|
this.computeSpreadBlockLight(x, y + 1, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeNormal(int x, int y, int z, int currentLight, Queue<MutableBlockVector3> queue, Map<MutableBlockVector3, Object> visited) {
|
||||||
|
{
|
||||||
|
// Block East
|
||||||
|
BlockState state = this.queue.getBlock(x + 1, y, z);
|
||||||
|
if (checkStairEast(state) && (isSlabOrTrueValue(state, "top") || isSlabOrTrueValue(state, "bottom"))) {
|
||||||
|
this.computeSpreadBlockLight(x + 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block West
|
||||||
|
BlockState state = this.queue.getBlock(x - 1, y, z);
|
||||||
|
if (checkStairWest(state) && (isSlabOrTrueValue(state, "top") || isSlabOrTrueValue(state, "bottom"))) {
|
||||||
|
this.computeSpreadBlockLight(x - 1, y, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block South
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z + 1);
|
||||||
|
if (checkStairSouth(state) && (isSlabOrTrueValue(state, "top") || isSlabOrTrueValue(state, "bottom"))) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z + 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// Block North
|
||||||
|
BlockState state = this.queue.getBlock(x, y, z - 1);
|
||||||
|
if (checkStairNorth(state) && (isSlabOrTrueValue(state, "top") || isSlabOrTrueValue(state, "bottom"))) {
|
||||||
|
this.computeSpreadBlockLight(x, y, z - 1, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BlockState state = this.queue.getBlock(x, y - 1, z);
|
||||||
|
if (y > 0 && isSlabOrTrueValue(state, "bottom") && isStairOrTrueTop(state, false)) {
|
||||||
|
this.computeSpreadBlockLight(x, y - 1, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
state = this.queue.getBlock(x, y + 1, z);
|
||||||
|
if (y < 255 && isSlabOrTrueValue(state, "top") && isStairOrTrueTop(state, false)) {
|
||||||
|
this.computeSpreadBlockLight(x, y + 1, z, currentLight, queue, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkStairNorth(BlockState state) {
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Direction direction = getStairDir(state);
|
||||||
|
String shape = getStairShape(state);
|
||||||
|
if (shape.contains("outer") || direction == Direction.NORTH) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (direction == Direction.SOUTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (direction == Direction.WEST) {
|
||||||
|
return !shape.equals("inner_left");
|
||||||
|
}
|
||||||
|
return direction != Direction.EAST || !shape.equals("inner_right");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkStairSouth(BlockState state) {
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Direction direction = getStairDir(state);
|
||||||
|
String shape = getStairShape(state);
|
||||||
|
if (shape.contains("outer") || direction == Direction.SOUTH) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (direction == Direction.NORTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (direction == Direction.EAST) {
|
||||||
|
return !shape.equals("inner_left");
|
||||||
|
}
|
||||||
|
return direction != Direction.WEST || !shape.equals("inner_right");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkStairEast(BlockState state) {
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Direction direction = getStairDir(state);
|
||||||
|
String shape = getStairShape(state);
|
||||||
|
if (shape.contains("outer") || direction == Direction.EAST) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (direction == Direction.WEST) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (direction == Direction.NORTH) {
|
||||||
|
return !shape.equals("inner_left");
|
||||||
|
}
|
||||||
|
return direction != Direction.SOUTH || !shape.equals("inner_right");
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkStairWest(BlockState state) {
|
||||||
|
if (!state.getBlockType().getId().toLowerCase().contains("stair")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Direction direction = getStairDir(state);
|
||||||
|
String shape = getStairShape(state);
|
||||||
|
if (shape.contains("outer") || direction == Direction.WEST) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (direction == Direction.EAST) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (direction == Direction.SOUTH) {
|
||||||
|
return !shape.equals("inner_left");
|
||||||
|
}
|
||||||
|
return direction != Direction.NORTH || !shape.equals("inner_right");
|
||||||
|
}
|
||||||
|
|
||||||
|
private Direction getStairDir(BlockState state) {
|
||||||
|
return state.getState(stairDirection);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getStairShape(BlockState state) {
|
||||||
|
return state.getState(stairShape).toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isStairOrTrueTop(BlockState state, boolean top) {
|
||||||
|
return !state.getBlockType().getId().contains("stair") || state.getState(stairHalf).equals("top") == top;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isSlabOrTrueValue(BlockState state, String value) {
|
||||||
|
return !state.getBlockType().getId().contains("slab") || state.getState(slabHalf).equals(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeRemoveBlockLight(int x,
|
||||||
|
int y,
|
||||||
|
int z,
|
||||||
|
int currentLight,
|
||||||
|
Queue<Object[]> queue,
|
||||||
|
Queue<MutableBlockVector3> spreadQueue,
|
||||||
|
Map<MutableBlockVector3, Object> visited,
|
||||||
Map<MutableBlockVector3, Object> spreadVisited) {
|
Map<MutableBlockVector3, Object> spreadVisited) {
|
||||||
ChunkHolder iChunk = (ChunkHolder) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(this.queue, x >> 4, z >> 4);
|
iChunk.init(this.queue, x >> 4, z >> 4);
|
||||||
}
|
}
|
||||||
@ -270,7 +704,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
if (!visited.containsKey(mutableBlockPos)) {
|
if (!visited.containsKey(mutableBlockPos)) {
|
||||||
MutableBlockVector3 index = new MutableBlockVector3(x, y, z);
|
MutableBlockVector3 index = new MutableBlockVector3(x, y, z);
|
||||||
visited.put(index, present);
|
visited.put(index, present);
|
||||||
queue.add(new Object[]{index, current});
|
queue.add(new Object[] {index, current});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (current >= currentLight) {
|
} else if (current >= currentLight) {
|
||||||
@ -283,16 +717,23 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeSpreadBlockLight(int x, int y, int z, int currentLight, Queue<MutableBlockVector3> queue, Map<MutableBlockVector3, Object> visited) {
|
private void computeSpreadBlockLight(int x,
|
||||||
currentLight = currentLight - Math.max(1, this.queue.getOpacity(x, y, z));
|
int y,
|
||||||
|
int z,
|
||||||
|
int currentLight,
|
||||||
|
Queue<MutableBlockVector3> queue,
|
||||||
|
Map<MutableBlockVector3, Object> visited) {
|
||||||
|
BlockMaterial material = this.queue.getBlock(x, y, z).getMaterial();
|
||||||
|
boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0 && material.getLightValue() == 0;
|
||||||
|
currentLight = !solidNeedsLight ? currentLight - Math.max(1, material.getLightOpacity()) : currentLight - 1;
|
||||||
if (currentLight > 0) {
|
if (currentLight > 0) {
|
||||||
ChunkHolder iChunk = (ChunkHolder) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(this.queue, x >> 4, z >> 4);
|
iChunk.init(this.queue, x >> 4, z >> 4);
|
||||||
}
|
}
|
||||||
int current = iChunk.getEmmittedLight(x & 15, y, z & 15);
|
int current = iChunk.getEmmittedLight(x & 15, y, z & 15);
|
||||||
if (current < currentLight) {
|
if (currentLight > current) {
|
||||||
iChunk.setBlockLight(x, y, z, currentLight);
|
iChunk.setBlockLight(x & 15, y, z & 15, currentLight);
|
||||||
mutableBlockPos.setComponents(x, y, z);
|
mutableBlockPos.setComponents(x, y, z);
|
||||||
if (!visited.containsKey(mutableBlockPos)) {
|
if (!visited.containsKey(mutableBlockPos)) {
|
||||||
visited.put(new MutableBlockVector3(x, y, z), present);
|
visited.put(new MutableBlockVector3(x, y, z), present);
|
||||||
@ -305,7 +746,9 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void fixLightingSafe(boolean sky) {
|
public void fixLightingSafe(boolean sky) {
|
||||||
if (isEmpty()) return;
|
if (isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if (sky) {
|
if (sky) {
|
||||||
fixSkyLighting();
|
fixSkyLighting();
|
||||||
@ -328,7 +771,8 @@ public class NMSRelighter implements Relighter {
|
|||||||
|
|
||||||
public void fixBlockLighting() {
|
public void fixBlockLighting() {
|
||||||
synchronized (lightQueue) {
|
synchronized (lightQueue) {
|
||||||
while (!lightLock.compareAndSet(false, true));
|
while (!lightLock.compareAndSet(false, true))
|
||||||
|
;
|
||||||
try {
|
try {
|
||||||
updateBlockLight(this.lightQueue);
|
updateBlockLight(this.lightQueue);
|
||||||
} finally {
|
} finally {
|
||||||
@ -345,7 +789,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
int bitMask = entry.getValue();
|
int bitMask = entry.getValue();
|
||||||
int x = MathMan.unpairIntX(pair);
|
int x = MathMan.unpairIntX(pair);
|
||||||
int z = MathMan.unpairIntY(pair);
|
int z = MathMan.unpairIntY(pair);
|
||||||
ChunkHolder chunk = (ChunkHolder) queue.getOrCreateChunk(x, z);
|
ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z);
|
||||||
chunk.setBitMask(bitMask);
|
chunk.setBitMask(bitMask);
|
||||||
iter.remove();
|
iter.remove();
|
||||||
}
|
}
|
||||||
@ -439,7 +883,7 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
int bx = chunk.x << 4;
|
int bx = chunk.x << 4;
|
||||||
int bz = chunk.z << 4;
|
int bz = chunk.z << 4;
|
||||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(queue, chunk.x, chunk.z);
|
iChunk.init(queue, chunk.x, chunk.z);
|
||||||
}
|
}
|
||||||
@ -453,9 +897,10 @@ public class NMSRelighter implements Relighter {
|
|||||||
int x = j & 15;
|
int x = j & 15;
|
||||||
int z = j >> 4;
|
int z = j >> 4;
|
||||||
byte value = mask[j];
|
byte value = mask[j];
|
||||||
byte pair = MathMan.pair16(iChunk.getOpacity(x, y, z), iChunk.getBrightness(x, y, z));
|
BlockMaterial material = iChunk.getBlock(x, y, z).getBlockType().getMaterial();
|
||||||
int opacity = MathMan.unpair16x(pair);
|
int opacity = material.getLightOpacity();
|
||||||
int brightness = MathMan.unpair16y(pair);
|
int brightness = iChunk.getBrightness(x, y, z);
|
||||||
|
boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0;
|
||||||
if (brightness > 1) {
|
if (brightness > 1) {
|
||||||
addLightUpdate(bx + x, y, bz + z);
|
addLightUpdate(bx + x, y, bz + z);
|
||||||
}
|
}
|
||||||
@ -482,7 +927,11 @@ public class NMSRelighter implements Relighter {
|
|||||||
case 14:
|
case 14:
|
||||||
if (opacity >= value) {
|
if (opacity >= value) {
|
||||||
mask[j] = 0;
|
mask[j] = 0;
|
||||||
|
if (solidNeedsLight) {
|
||||||
|
iChunk.setSkyLight(x, y, z, value);
|
||||||
|
} else {
|
||||||
iChunk.setSkyLight(x, y, z, 0);
|
iChunk.setSkyLight(x, y, z, 0);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opacity <= 1) {
|
if (opacity <= 1) {
|
||||||
@ -496,7 +945,11 @@ public class NMSRelighter implements Relighter {
|
|||||||
value -= opacity;
|
value -= opacity;
|
||||||
mask[j] = value;
|
mask[j] = value;
|
||||||
}
|
}
|
||||||
|
if (solidNeedsLight) {
|
||||||
|
iChunk.setSkyLight(x, y, z, value + opacity);
|
||||||
|
} else {
|
||||||
iChunk.setSkyLight(x, y, z, value);
|
iChunk.setSkyLight(x, y, z, value);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
chunk.smooth = true;
|
chunk.smooth = true;
|
||||||
@ -519,15 +972,15 @@ public class NMSRelighter implements Relighter {
|
|||||||
|
|
||||||
public void smoothSkyLight(RelightSkyEntry chunk, int y, boolean direction) {
|
public void smoothSkyLight(RelightSkyEntry chunk, int y, boolean direction) {
|
||||||
byte[] mask = chunk.mask;
|
byte[] mask = chunk.mask;
|
||||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z);
|
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||||
ChunkHolder iChunkx;
|
ChunkHolder<?> iChunkx;
|
||||||
ChunkHolder iChunkz;
|
ChunkHolder<?> iChunkz;
|
||||||
if (!iChunk.isInit()) {
|
if (!iChunk.isInit()) {
|
||||||
iChunk.init(queue, chunk.x, chunk.z);
|
iChunk.init(queue, chunk.x, chunk.z);
|
||||||
}
|
}
|
||||||
if (direction) {
|
if (direction) {
|
||||||
iChunkx = (ChunkHolder) queue.getOrCreateChunk(chunk.x - 1, chunk.z);
|
iChunkx = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x - 1, chunk.z);
|
||||||
iChunkz = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z - 1);
|
iChunkz = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z - 1);
|
||||||
if (!iChunkx.isInit()) {
|
if (!iChunkx.isInit()) {
|
||||||
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
||||||
}
|
}
|
||||||
@ -542,26 +995,38 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
byte value = mask[j];
|
byte value = mask[j];
|
||||||
if (x != 0 && z != 0) {
|
if (x != 0 && z != 0) {
|
||||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else if (x == 0 && z == 0) {
|
} else if (x == 0 && z == 0) {
|
||||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else if (x == 0) {
|
} else if (x == 0) {
|
||||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunkx.getSkyLight(15, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z - 1) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunk.getSkyLight(x - 1, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 15) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iChunkx = (ChunkHolder) queue.getOrCreateChunk(chunk.x + 1, chunk.z);
|
iChunkx = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x + 1, chunk.z);
|
||||||
iChunkz = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z + 1);
|
iChunkz = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z + 1);
|
||||||
if (!iChunkx.isInit()) {
|
if (!iChunkx.isInit()) {
|
||||||
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
||||||
}
|
}
|
||||||
@ -575,22 +1040,34 @@ public class NMSRelighter implements Relighter {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
byte value = mask[j];
|
byte value = mask[j];
|
||||||
if ( x != 15 && z != 15) {
|
if (x != 15 && z != 15) {
|
||||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else if (x == 15 && z == 15) {
|
} else if (x == 15 && z == 15) {
|
||||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else if (x == 15) {
|
} else if (x == 15) {
|
||||||
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunkx.getSkyLight(0, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunk.getSkyLight(x, y, z + 1) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) ;
|
if ((value = (byte) Math.max(iChunk.getSkyLight(x + 1, y, z) - 1, value)) >= 14) {
|
||||||
else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) ;
|
} else if ((value = (byte) Math.max(iChunkz.getSkyLight(x, y, 0) - 1, value)) >= 14) {
|
||||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
}
|
||||||
|
if (value > mask[j]) {
|
||||||
|
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -619,13 +1096,11 @@ public class NMSRelighter implements Relighter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public String toString() {
|
||||||
public String toString() {
|
|
||||||
return x + "," + z;
|
return x + "," + z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public int compareTo(RelightSkyEntry o) {
|
||||||
public int compareTo(RelightSkyEntry o) {
|
|
||||||
if (o.x < x) {
|
if (o.x < x) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -480,7 +480,7 @@ public class Settings extends Config {
|
|||||||
})
|
})
|
||||||
public int MODE = 1;
|
public int MODE = 1;
|
||||||
@Comment({"If existing lighting should be removed before relighting"})
|
@Comment({"If existing lighting should be removed before relighting"})
|
||||||
public boolean REMOVE_FIRST = false;
|
public boolean REMOVE_FIRST = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reload(File file) {
|
public void reload(File file) {
|
||||||
|
Loading…
Reference in New Issue
Block a user