154 lines
5.1 KiB
Java
154 lines
5.1 KiB
Java
package net.minecraft.world.level.lighting;
|
|
|
|
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
|
|
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.core.SectionPos;
|
|
import net.minecraft.world.level.LightLayer;
|
|
import net.minecraft.world.level.chunk.DataLayer;
|
|
import net.minecraft.world.level.chunk.LightChunkGetter;
|
|
|
|
public class SkyLightSectionStorage extends LayerLightSectionStorage<SkyLightSectionStorage.SkyDataLayerStorageMap> {
|
|
protected SkyLightSectionStorage(LightChunkGetter chunkSource) {
|
|
super(
|
|
LightLayer.SKY, chunkSource, new SkyLightSectionStorage.SkyDataLayerStorageMap(new Long2ObjectOpenHashMap<>(), new Long2IntOpenHashMap(), Integer.MAX_VALUE)
|
|
);
|
|
}
|
|
|
|
@Override
|
|
protected int getLightValue(long levelPos) {
|
|
return this.getLightValue(levelPos, false);
|
|
}
|
|
|
|
protected int getLightValue(long packedPos, boolean updateAll) {
|
|
long l = SectionPos.blockToSection(packedPos);
|
|
int i = SectionPos.y(l);
|
|
SkyLightSectionStorage.SkyDataLayerStorageMap skyDataLayerStorageMap = updateAll ? this.updatingSectionData : this.visibleSectionData;
|
|
int j = skyDataLayerStorageMap.topSections.get(SectionPos.getZeroNode(l));
|
|
if (j != skyDataLayerStorageMap.currentLowestY && i < j) {
|
|
DataLayer dataLayer = this.getDataLayer(skyDataLayerStorageMap, l);
|
|
if (dataLayer == null) {
|
|
for (packedPos = BlockPos.getFlatIndex(packedPos); dataLayer == null; dataLayer = this.getDataLayer(skyDataLayerStorageMap, l)) {
|
|
if (++i >= j) {
|
|
return 15;
|
|
}
|
|
|
|
l = SectionPos.offset(l, Direction.UP);
|
|
}
|
|
}
|
|
|
|
return dataLayer.get(
|
|
SectionPos.sectionRelative(BlockPos.getX(packedPos)),
|
|
SectionPos.sectionRelative(BlockPos.getY(packedPos)),
|
|
SectionPos.sectionRelative(BlockPos.getZ(packedPos))
|
|
);
|
|
} else {
|
|
return updateAll && !this.lightOnInSection(l) ? 0 : 15;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onNodeAdded(long sectionPos) {
|
|
int i = SectionPos.y(sectionPos);
|
|
if (this.updatingSectionData.currentLowestY > i) {
|
|
this.updatingSectionData.currentLowestY = i;
|
|
this.updatingSectionData.topSections.defaultReturnValue(this.updatingSectionData.currentLowestY);
|
|
}
|
|
|
|
long l = SectionPos.getZeroNode(sectionPos);
|
|
int j = this.updatingSectionData.topSections.get(l);
|
|
if (j < i + 1) {
|
|
this.updatingSectionData.topSections.put(l, i + 1);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected void onNodeRemoved(long sectionPos) {
|
|
long l = SectionPos.getZeroNode(sectionPos);
|
|
int i = SectionPos.y(sectionPos);
|
|
if (this.updatingSectionData.topSections.get(l) == i + 1) {
|
|
long m;
|
|
for (m = sectionPos; !this.storingLightForSection(m) && this.hasLightDataAtOrBelow(i); m = SectionPos.offset(m, Direction.DOWN)) {
|
|
i--;
|
|
}
|
|
|
|
if (this.storingLightForSection(m)) {
|
|
this.updatingSectionData.topSections.put(l, i + 1);
|
|
} else {
|
|
this.updatingSectionData.topSections.remove(l);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
protected DataLayer createDataLayer(long sectionPos) {
|
|
DataLayer dataLayer = this.queuedSections.get(sectionPos);
|
|
if (dataLayer != null) {
|
|
return dataLayer;
|
|
} else {
|
|
int i = this.updatingSectionData.topSections.get(SectionPos.getZeroNode(sectionPos));
|
|
if (i != this.updatingSectionData.currentLowestY && SectionPos.y(sectionPos) < i) {
|
|
long l = SectionPos.offset(sectionPos, Direction.UP);
|
|
|
|
DataLayer dataLayer2;
|
|
while ((dataLayer2 = this.getDataLayer(l, true)) == null) {
|
|
l = SectionPos.offset(l, Direction.UP);
|
|
}
|
|
|
|
return repeatFirstLayer(dataLayer2);
|
|
} else {
|
|
return this.lightOnInSection(sectionPos) ? new DataLayer(15) : new DataLayer();
|
|
}
|
|
}
|
|
}
|
|
|
|
private static DataLayer repeatFirstLayer(DataLayer dataLayer) {
|
|
if (dataLayer.isDefinitelyHomogenous()) {
|
|
return dataLayer.copy();
|
|
} else {
|
|
byte[] bs = dataLayer.getData();
|
|
byte[] cs = new byte[2048];
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
System.arraycopy(bs, 0, cs, i * 128, 128);
|
|
}
|
|
|
|
return new DataLayer(cs);
|
|
}
|
|
}
|
|
|
|
protected boolean hasLightDataAtOrBelow(int y) {
|
|
return y >= this.updatingSectionData.currentLowestY;
|
|
}
|
|
|
|
protected boolean isAboveData(long sectionPos) {
|
|
long l = SectionPos.getZeroNode(sectionPos);
|
|
int i = this.updatingSectionData.topSections.get(l);
|
|
return i == this.updatingSectionData.currentLowestY || SectionPos.y(sectionPos) >= i;
|
|
}
|
|
|
|
protected int getTopSectionY(long sectionPos) {
|
|
return this.updatingSectionData.topSections.get(sectionPos);
|
|
}
|
|
|
|
protected int getBottomSectionY() {
|
|
return this.updatingSectionData.currentLowestY;
|
|
}
|
|
|
|
protected static final class SkyDataLayerStorageMap extends DataLayerStorageMap<SkyLightSectionStorage.SkyDataLayerStorageMap> {
|
|
int currentLowestY;
|
|
final Long2IntOpenHashMap topSections;
|
|
|
|
public SkyDataLayerStorageMap(Long2ObjectOpenHashMap<DataLayer> map, Long2IntOpenHashMap topSections, int currentLowestY) {
|
|
super(map);
|
|
this.topSections = topSections;
|
|
topSections.defaultReturnValue(currentLowestY);
|
|
this.currentLowestY = currentLowestY;
|
|
}
|
|
|
|
public SkyLightSectionStorage.SkyDataLayerStorageMap copy() {
|
|
return new SkyLightSectionStorage.SkyDataLayerStorageMap(this.map.clone(), this.topSections.clone(), this.currentLowestY);
|
|
}
|
|
}
|
|
}
|