213 lines
9.2 KiB
Java
213 lines
9.2 KiB
Java
package net.minecraft.world.level.lighting;
|
|
|
|
import net.minecraft.world.level.chunk.DataLayer;
|
|
import net.minecraft.core.SectionPos;
|
|
import net.minecraft.world.phys.shapes.VoxelShape;
|
|
import net.minecraft.world.level.block.state.BlockState;
|
|
import net.minecraft.world.phys.shapes.Shapes;
|
|
import net.minecraft.core.BlockPos;
|
|
import org.apache.commons.lang3.mutable.MutableInt;
|
|
import net.minecraft.world.level.LightLayer;
|
|
import net.minecraft.world.level.chunk.LightChunkGetter;
|
|
import net.minecraft.core.Direction;
|
|
|
|
public final class SkyLightEngine extends LayerLightEngine<SkyLightSectionStorage.SkyDataLayerStorageMap, SkyLightSectionStorage> {
|
|
private static final Direction[] DIRECTIONS;
|
|
private static final Direction[] HORIZONTALS;
|
|
|
|
public SkyLightEngine(final LightChunkGetter cak) {
|
|
super(cak, LightLayer.SKY, new SkyLightSectionStorage(cak));
|
|
}
|
|
|
|
@Override
|
|
protected int computeLevelFromNeighbor(final long long1, final long long2, int integer) {
|
|
if (long2 == Long.MAX_VALUE) {
|
|
return 15;
|
|
}
|
|
if (long1 == Long.MAX_VALUE) {
|
|
if (!((SkyLightSectionStorage)this.storage).hasLightSource(long2)) {
|
|
return 15;
|
|
}
|
|
integer = 0;
|
|
}
|
|
if (integer >= 15) {
|
|
return integer;
|
|
}
|
|
final MutableInt mutableInt7 = new MutableInt();
|
|
final BlockState byg8 = this.getStateAndOpacity(long2, mutableInt7);
|
|
if (mutableInt7.getValue() >= 15) {
|
|
return 15;
|
|
}
|
|
final int integer2 = BlockPos.getX(long1);
|
|
final int integer3 = BlockPos.getY(long1);
|
|
final int integer4 = BlockPos.getZ(long1);
|
|
final int integer5 = BlockPos.getX(long2);
|
|
final int integer6 = BlockPos.getY(long2);
|
|
final int integer7 = BlockPos.getZ(long2);
|
|
final boolean boolean15 = integer2 == integer5 && integer4 == integer7;
|
|
final int integer8 = Integer.signum(integer5 - integer2);
|
|
final int integer9 = Integer.signum(integer6 - integer3);
|
|
final int integer10 = Integer.signum(integer7 - integer4);
|
|
Direction fp19;
|
|
if (long1 == Long.MAX_VALUE) {
|
|
fp19 = Direction.DOWN;
|
|
}
|
|
else {
|
|
fp19 = Direction.fromNormal(integer8, integer9, integer10);
|
|
}
|
|
final BlockState byg9 = this.getStateAndOpacity(long1, null);
|
|
if (fp19 != null) {
|
|
final VoxelShape cwc21 = this.getShape(byg9, long1, fp19);
|
|
final VoxelShape cwc22 = this.getShape(byg8, long2, fp19.getOpposite());
|
|
if (Shapes.faceShapeOccludes(cwc21, cwc22)) {
|
|
return 15;
|
|
}
|
|
}
|
|
else {
|
|
final VoxelShape cwc21 = this.getShape(byg9, long1, Direction.DOWN);
|
|
if (Shapes.faceShapeOccludes(cwc21, Shapes.empty())) {
|
|
return 15;
|
|
}
|
|
final int integer11 = boolean15 ? -1 : 0;
|
|
final Direction fp20 = Direction.fromNormal(integer8, integer11, integer10);
|
|
if (fp20 == null) {
|
|
return 15;
|
|
}
|
|
final VoxelShape cwc23 = this.getShape(byg8, long2, fp20.getOpposite());
|
|
if (Shapes.faceShapeOccludes(Shapes.empty(), cwc23)) {
|
|
return 15;
|
|
}
|
|
}
|
|
final boolean boolean16 = long1 == Long.MAX_VALUE || (boolean15 && integer3 > integer6);
|
|
if (boolean16 && integer == 0 && mutableInt7.getValue() == 0) {
|
|
return 0;
|
|
}
|
|
return integer + Math.max(1, mutableInt7.getValue());
|
|
}
|
|
|
|
@Override
|
|
protected void checkNeighborsAfterUpdate(final long long1, final int integer, final boolean boolean3) {
|
|
final long long2 = SectionPos.blockToSection(long1);
|
|
final int integer2 = BlockPos.getY(long1);
|
|
final int integer3 = SectionPos.sectionRelative(integer2);
|
|
final int integer4 = SectionPos.blockToSectionCoord(integer2);
|
|
int integer5;
|
|
if (integer3 != 0) {
|
|
integer5 = 0;
|
|
}
|
|
else {
|
|
int integer6;
|
|
for (integer6 = 0; !((SkyLightSectionStorage)this.storage).storingLightForSection(SectionPos.offset(long2, 0, -integer6 - 1, 0)) && ((SkyLightSectionStorage)this.storage).hasSectionsBelow(integer4 - integer6 - 1); ++integer6) {}
|
|
integer5 = integer6;
|
|
}
|
|
final long long3 = BlockPos.offset(long1, 0, -1 - integer5 * 16, 0);
|
|
final long long4 = SectionPos.blockToSection(long3);
|
|
if (long2 == long4 || ((SkyLightSectionStorage)this.storage).storingLightForSection(long4)) {
|
|
this.checkNeighbor(long1, long3, integer, boolean3);
|
|
}
|
|
final long long5 = BlockPos.offset(long1, Direction.UP);
|
|
final long long6 = SectionPos.blockToSection(long5);
|
|
if (long2 == long6 || ((SkyLightSectionStorage)this.storage).storingLightForSection(long6)) {
|
|
this.checkNeighbor(long1, long5, integer, boolean3);
|
|
}
|
|
for (final Direction fp23 : SkyLightEngine.HORIZONTALS) {
|
|
int integer7 = 0;
|
|
do {
|
|
final long long7 = BlockPos.offset(long1, fp23.getStepX(), -integer7, fp23.getStepZ());
|
|
final long long8 = SectionPos.blockToSection(long7);
|
|
if (long2 == long8) {
|
|
this.checkNeighbor(long1, long7, integer, boolean3);
|
|
break;
|
|
}
|
|
if (!((SkyLightSectionStorage)this.storage).storingLightForSection(long8)) {
|
|
continue;
|
|
}
|
|
this.checkNeighbor(long1, long7, integer, boolean3);
|
|
} while (++integer7 <= integer5 * 16);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected int getComputedLevel(final long long1, final long long2, final int integer) {
|
|
int integer2 = integer;
|
|
if (Long.MAX_VALUE != long2) {
|
|
final int integer3 = this.computeLevelFromNeighbor(Long.MAX_VALUE, long1, 0);
|
|
if (integer2 > integer3) {
|
|
integer2 = integer3;
|
|
}
|
|
if (integer2 == 0) {
|
|
return integer2;
|
|
}
|
|
}
|
|
final long long3 = SectionPos.blockToSection(long1);
|
|
final DataLayer cac10 = ((SkyLightSectionStorage)this.storage).getDataLayer(long3, true);
|
|
for (final Direction fp14 : SkyLightEngine.DIRECTIONS) {
|
|
long long4 = BlockPos.offset(long1, fp14);
|
|
long long5 = SectionPos.blockToSection(long4);
|
|
DataLayer cac11;
|
|
if (long3 == long5) {
|
|
cac11 = cac10;
|
|
}
|
|
else {
|
|
cac11 = ((SkyLightSectionStorage)this.storage).getDataLayer(long5, true);
|
|
}
|
|
if (cac11 != null) {
|
|
if (long4 != long2) {
|
|
final int integer4 = this.computeLevelFromNeighbor(long4, long1, this.getLevel(cac11, long4));
|
|
if (integer2 > integer4) {
|
|
integer2 = integer4;
|
|
}
|
|
if (integer2 == 0) {
|
|
return integer2;
|
|
}
|
|
}
|
|
}
|
|
else if (fp14 != Direction.DOWN) {
|
|
for (long4 = BlockPos.getFlatIndex(long4); !((SkyLightSectionStorage)this.storage).storingLightForSection(long5) && !((SkyLightSectionStorage)this.storage).isAboveData(long5); long5 = SectionPos.offset(long5, Direction.UP), long4 = BlockPos.offset(long4, 0, 16, 0)) {}
|
|
final DataLayer cac12 = ((SkyLightSectionStorage)this.storage).getDataLayer(long5, true);
|
|
if (long4 != long2) {
|
|
int integer5;
|
|
if (cac12 != null) {
|
|
integer5 = this.computeLevelFromNeighbor(long4, long1, this.getLevel(cac12, long4));
|
|
}
|
|
else {
|
|
integer5 = (((SkyLightSectionStorage)this.storage).lightOnInSection(long5) ? 0 : 15);
|
|
}
|
|
if (integer2 > integer5) {
|
|
integer2 = integer5;
|
|
}
|
|
if (integer2 == 0) {
|
|
return integer2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return integer2;
|
|
}
|
|
|
|
@Override
|
|
protected void checkNode(long long1) {
|
|
((SkyLightSectionStorage)this.storage).runAllUpdates();
|
|
long long2 = SectionPos.blockToSection(long1);
|
|
if (((SkyLightSectionStorage)this.storage).storingLightForSection(long2)) {
|
|
super.checkNode(long1);
|
|
}
|
|
else {
|
|
for (long1 = BlockPos.getFlatIndex(long1); !((SkyLightSectionStorage)this.storage).storingLightForSection(long2) && !((SkyLightSectionStorage)this.storage).isAboveData(long2); long2 = SectionPos.offset(long2, Direction.UP), long1 = BlockPos.offset(long1, 0, 16, 0)) {}
|
|
if (((SkyLightSectionStorage)this.storage).storingLightForSection(long2)) {
|
|
super.checkNode(long1);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public String getDebugData(final long long1) {
|
|
return super.getDebugData(long1) + (((SkyLightSectionStorage)this.storage).isAboveData(long1) ? "*" : "");
|
|
}
|
|
|
|
static {
|
|
DIRECTIONS = Direction.values();
|
|
HORIZONTALS = new Direction[] { Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST };
|
|
}
|
|
}
|