minecraft-src/net/minecraft/world/level/lighting/SkyLightSectionStorage.java
2025-07-04 01:41:11 +03:00

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);
}
}
}