geforkt von Mirrors/FastAsyncWorldEdit
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
Dieser Commit ist enthalten in:
Ursprung
d00899e177
Commit
4243e8e86b
@ -381,8 +381,12 @@ public class FaweAPI {
|
||||
}
|
||||
}
|
||||
if (mode != RelightMode.NONE) {
|
||||
relighter.fixSkyLighting();
|
||||
relighter.fixBlockLighting();
|
||||
if (Settings.IMP.LIGHTING.REMOVE_FIRST) {
|
||||
relighter.removeAndRelight(true);
|
||||
} else {
|
||||
relighter.fixSkyLighting();
|
||||
relighter.fixBlockLighting();
|
||||
}
|
||||
} else {
|
||||
relighter.removeLighting();
|
||||
}
|
||||
|
@ -9,6 +9,13 @@ import com.boydti.fawe.object.collection.BlockVectorSet;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
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 java.util.ArrayDeque;
|
||||
@ -25,22 +32,29 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
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 Object present = new Object();
|
||||
private final Map<Long, Integer> chunksToSend;
|
||||
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 ConcurrentHashMap<Long, long[][][]> concurrentLightQueue;
|
||||
|
||||
private final int maxY;
|
||||
|
||||
public final MutableBlockVector3 mutableBlockPos = new MutableBlockVector3(0, 0, 0);
|
||||
|
||||
private static final int DISPATCH_SIZE = 64;
|
||||
private boolean removeFirst;
|
||||
|
||||
public NMSRelighter(IQueueExtent<IQueueChunk> queue) {
|
||||
@ -52,13 +66,11 @@ public class NMSRelighter implements Relighter {
|
||||
this.maxY = queue.getMaxY();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
@Override public boolean isEmpty() {
|
||||
return skyToRelight.isEmpty() && lightQueue.isEmpty() && extentdSkyToRelight.isEmpty() && concurrentLightQueue.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void removeAndRelight(boolean sky) {
|
||||
@Override public synchronized void removeAndRelight(boolean sky) {
|
||||
removeFirst = true;
|
||||
fixLightingSafe(sky);
|
||||
removeFirst = false;
|
||||
@ -67,9 +79,9 @@ public class NMSRelighter implements Relighter {
|
||||
/**
|
||||
* Utility method to reduce duplicated code to ensure values are written to long[][][] without NPEs
|
||||
*
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param z z coordinate
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @param z z coordinate
|
||||
* @param map long[][][] to add values to
|
||||
*/
|
||||
private void set(int x, int y, int z, long[][][] map) {
|
||||
@ -147,7 +159,7 @@ public class NMSRelighter implements Relighter {
|
||||
long pair = entry.getKey();
|
||||
Integer existing = chunksToSend.get(pair);
|
||||
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()) {
|
||||
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> 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();
|
||||
while (iter.hasNext() && size-- > 0) {
|
||||
Map.Entry<Long, long[][][]> entry = iter.next();
|
||||
@ -177,16 +192,20 @@ public class NMSRelighter implements Relighter {
|
||||
int chunkZ = MathMan.unpairIntY(index);
|
||||
int bx = chunkX << 4;
|
||||
int bz = chunkZ << 4;
|
||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunkX, chunkZ);
|
||||
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunkX, chunkZ);
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(queue, chunkX, chunkZ);
|
||||
}
|
||||
for (int lz = 0; lz < blocks.length; lz++) {
|
||||
long[][] m1 = blocks[lz];
|
||||
if (m1 == null) continue;
|
||||
if (m1 == null) {
|
||||
continue;
|
||||
}
|
||||
for (int lx = 0; lx < m1.length; lx++) {
|
||||
long[] m2 = m1[lx];
|
||||
if (m2 == null) continue;
|
||||
if (m2 == null) {
|
||||
continue;
|
||||
}
|
||||
for (int i = 0; i < m2.length; i++) {
|
||||
int yStart = i << 6;
|
||||
long value = m2[i];
|
||||
@ -203,7 +222,7 @@ public class NMSRelighter implements Relighter {
|
||||
MutableBlockVector3 node = new MutableBlockVector3(x, y, z);
|
||||
if (newLevel < oldLevel) {
|
||||
removalVisited.put(node, present);
|
||||
lightRemovalQueue.add(new Object[]{node, oldLevel});
|
||||
lightRemovalQueue.add(new Object[] {node, oldLevel});
|
||||
} else {
|
||||
visited.put(node, present);
|
||||
lightPropagationQueue.add(node);
|
||||
@ -223,43 +242,458 @@ public class NMSRelighter implements Relighter {
|
||||
MutableBlockVector3 node = (MutableBlockVector3) val[0];
|
||||
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, removalVisited, visited);
|
||||
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,
|
||||
removalVisited, visited);
|
||||
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) {
|
||||
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, 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,
|
||||
removalVisited, visited);
|
||||
}
|
||||
|
||||
while (!lightPropagationQueue.isEmpty()) {
|
||||
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()) {
|
||||
iChunk.init(queue, node.getX() >> 4, node.getZ() >> 4);
|
||||
}
|
||||
int lightLevel = iChunk.getEmmittedLight(node.getX() & 15, node.getY(), node.getZ() & 15);
|
||||
if (lightLevel > 1) {
|
||||
this.computeSpreadBlockLight(node.getX() - 1, node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited);
|
||||
this.computeSpreadBlockLight(node.getX() + 1, node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited);
|
||||
if (node.getY() > 0) {
|
||||
this.computeSpreadBlockLight(node.getX(), node.getY() - 1, node.getZ(), lightLevel, lightPropagationQueue, visited);
|
||||
}
|
||||
if (node.getY() < 255) {
|
||||
this.computeSpreadBlockLight(node.getX(), node.getY() + 1, node.getZ(), lightLevel, lightPropagationQueue, visited);
|
||||
}
|
||||
this.computeSpreadBlockLight(node.getX(), node.getY(), node.getZ() - 1, lightLevel, lightPropagationQueue, visited);
|
||||
this.computeSpreadBlockLight(node.getX(), node.getY(), node.getZ() + 1, lightLevel, lightPropagationQueue, visited);
|
||||
BlockState state = this.queue.getBlock(node.getX(), node.getY(), node.getZ());
|
||||
String id = state.getBlockType().getId().toLowerCase();
|
||||
if (lightLevel <= 1) {
|
||||
continue;
|
||||
}
|
||||
if (id.contains("slab")) {
|
||||
boolean top = state.getState(slabHalf).equalsIgnoreCase("top");
|
||||
computeSlab(node.getX(), node.getY(), node.getZ(), lightLevel, lightPropagationQueue, visited, top);
|
||||
} else if (id.contains("stair")) {
|
||||
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,
|
||||
Map<MutableBlockVector3, Object> spreadVisited) {
|
||||
ChunkHolder iChunk = (ChunkHolder) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||
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) {
|
||||
ChunkHolder<?> iChunk = (ChunkHolder<?>) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(this.queue, x >> 4, z >> 4);
|
||||
}
|
||||
@ -270,7 +704,7 @@ public class NMSRelighter implements Relighter {
|
||||
if (!visited.containsKey(mutableBlockPos)) {
|
||||
MutableBlockVector3 index = new MutableBlockVector3(x, y, z);
|
||||
visited.put(index, present);
|
||||
queue.add(new Object[]{index, current});
|
||||
queue.add(new Object[] {index, current});
|
||||
}
|
||||
}
|
||||
} 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) {
|
||||
currentLight = currentLight - Math.max(1, this.queue.getOpacity(x, y, z));
|
||||
private void computeSpreadBlockLight(int x,
|
||||
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) {
|
||||
ChunkHolder iChunk = (ChunkHolder) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||
ChunkHolder<?> iChunk = (ChunkHolder<?>) this.queue.getOrCreateChunk(x >> 4, z >> 4);
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(this.queue, x >> 4, z >> 4);
|
||||
}
|
||||
int current = iChunk.getEmmittedLight(x & 15, y, z & 15);
|
||||
if (current < currentLight) {
|
||||
iChunk.setBlockLight(x, y, z, currentLight);
|
||||
if (currentLight > current) {
|
||||
iChunk.setBlockLight(x & 15, y, z & 15, currentLight);
|
||||
mutableBlockPos.setComponents(x, y, z);
|
||||
if (!visited.containsKey(mutableBlockPos)) {
|
||||
visited.put(new MutableBlockVector3(x, y, z), present);
|
||||
@ -305,7 +746,9 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
|
||||
public void fixLightingSafe(boolean sky) {
|
||||
if (isEmpty()) return;
|
||||
if (isEmpty()) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (sky) {
|
||||
fixSkyLighting();
|
||||
@ -328,7 +771,8 @@ public class NMSRelighter implements Relighter {
|
||||
|
||||
public void fixBlockLighting() {
|
||||
synchronized (lightQueue) {
|
||||
while (!lightLock.compareAndSet(false, true));
|
||||
while (!lightLock.compareAndSet(false, true))
|
||||
;
|
||||
try {
|
||||
updateBlockLight(this.lightQueue);
|
||||
} finally {
|
||||
@ -345,7 +789,7 @@ public class NMSRelighter implements Relighter {
|
||||
int bitMask = entry.getValue();
|
||||
int x = MathMan.unpairIntX(pair);
|
||||
int z = MathMan.unpairIntY(pair);
|
||||
ChunkHolder chunk = (ChunkHolder) queue.getOrCreateChunk(x, z);
|
||||
ChunkHolder<?> chunk = (ChunkHolder<?>) queue.getOrCreateChunk(x, z);
|
||||
chunk.setBitMask(bitMask);
|
||||
iter.remove();
|
||||
}
|
||||
@ -439,7 +883,7 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
int bx = chunk.x << 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()) {
|
||||
iChunk.init(queue, chunk.x, chunk.z);
|
||||
}
|
||||
@ -453,9 +897,10 @@ public class NMSRelighter implements Relighter {
|
||||
int x = j & 15;
|
||||
int z = j >> 4;
|
||||
byte value = mask[j];
|
||||
byte pair = MathMan.pair16(iChunk.getOpacity(x, y, z), iChunk.getBrightness(x, y, z));
|
||||
int opacity = MathMan.unpair16x(pair);
|
||||
int brightness = MathMan.unpair16y(pair);
|
||||
BlockMaterial material = iChunk.getBlock(x, y, z).getBlockType().getMaterial();
|
||||
int opacity = material.getLightOpacity();
|
||||
int brightness = iChunk.getBrightness(x, y, z);
|
||||
boolean solidNeedsLight = (!material.isSolid() || !material.isFullCube()) && material.getLightOpacity() > 0;
|
||||
if (brightness > 1) {
|
||||
addLightUpdate(bx + x, y, bz + z);
|
||||
}
|
||||
@ -482,7 +927,11 @@ public class NMSRelighter implements Relighter {
|
||||
case 14:
|
||||
if (opacity >= value) {
|
||||
mask[j] = 0;
|
||||
iChunk.setSkyLight(x, y, z, 0);
|
||||
if (solidNeedsLight) {
|
||||
iChunk.setSkyLight(x, y, z, value);
|
||||
} else {
|
||||
iChunk.setSkyLight(x, y, z, 0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (opacity <= 1) {
|
||||
@ -496,7 +945,11 @@ public class NMSRelighter implements Relighter {
|
||||
value -= opacity;
|
||||
mask[j] = value;
|
||||
}
|
||||
iChunk.setSkyLight(x, y, z, value);
|
||||
if (solidNeedsLight) {
|
||||
iChunk.setSkyLight(x, y, z, value + opacity);
|
||||
} else {
|
||||
iChunk.setSkyLight(x, y, z, value);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
chunk.smooth = true;
|
||||
@ -519,15 +972,15 @@ public class NMSRelighter implements Relighter {
|
||||
|
||||
public void smoothSkyLight(RelightSkyEntry chunk, int y, boolean direction) {
|
||||
byte[] mask = chunk.mask;
|
||||
ChunkHolder iChunk = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||
ChunkHolder iChunkx;
|
||||
ChunkHolder iChunkz;
|
||||
ChunkHolder<?> iChunk = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z);
|
||||
ChunkHolder<?> iChunkx;
|
||||
ChunkHolder<?> iChunkz;
|
||||
if (!iChunk.isInit()) {
|
||||
iChunk.init(queue, chunk.x, chunk.z);
|
||||
}
|
||||
if (direction) {
|
||||
iChunkx = (ChunkHolder) queue.getOrCreateChunk(chunk.x - 1, chunk.z);
|
||||
iChunkz = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z - 1);
|
||||
iChunkx = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x - 1, chunk.z);
|
||||
iChunkz = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z - 1);
|
||||
if (!iChunkx.isInit()) {
|
||||
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
||||
}
|
||||
@ -542,26 +995,38 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
byte value = mask[j];
|
||||
if (x != 0 && z != 0) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 0 && z == 0) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 0) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
iChunkx = (ChunkHolder) queue.getOrCreateChunk(chunk.x + 1, chunk.z);
|
||||
iChunkz = (ChunkHolder) queue.getOrCreateChunk(chunk.x, chunk.z + 1);
|
||||
iChunkx = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x + 1, chunk.z);
|
||||
iChunkz = (ChunkHolder<?>) queue.getOrCreateChunk(chunk.x, chunk.z + 1);
|
||||
if (!iChunkx.isInit()) {
|
||||
iChunkx.init(queue, chunk.x - 1, chunk.z);
|
||||
}
|
||||
@ -575,22 +1040,34 @@ public class NMSRelighter implements Relighter {
|
||||
continue;
|
||||
}
|
||||
byte value = mask[j];
|
||||
if ( x != 15 && z != 15) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
if (x != 15 && z != 15) {
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 15 && z == 15) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else if (x == 15) {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
} else {
|
||||
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) ;
|
||||
if (value > mask[j]) iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
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) {
|
||||
}
|
||||
if (value > mask[j]) {
|
||||
iChunk.setSkyLight(x, y, z, mask[j] = value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -619,13 +1096,11 @@ public class NMSRelighter implements Relighter {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
@Override public String toString() {
|
||||
return x + "," + z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(RelightSkyEntry o) {
|
||||
@Override public int compareTo(RelightSkyEntry o) {
|
||||
if (o.x < x) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -480,7 +480,7 @@ public class Settings extends Config {
|
||||
})
|
||||
public int MODE = 1;
|
||||
@Comment({"If existing lighting should be removed before relighting"})
|
||||
public boolean REMOVE_FIRST = false;
|
||||
public boolean REMOVE_FIRST = true;
|
||||
}
|
||||
|
||||
public void reload(File file) {
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren