Fixed WorldGen to provide better support for StarLight

This commit is contained in:
tom lee
2022-01-22 22:38:33 +08:00
parent 223570a0b7
commit 8500ec7a00
2 changed files with 216 additions and 26 deletions
@@ -53,6 +53,8 @@ import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.WorldGenRegion;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.BlockGetter;
import net.minecraft.world.level.ChunkPos;
import net.minecraft.world.level.LevelHeightAccessor;
@@ -60,9 +62,15 @@ import net.minecraft.world.level.LightLayer;
import net.minecraft.world.level.StructureFeatureManager;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.BiomeManager;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.EntityBlock;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.chunk.ChunkAccess;
import net.minecraft.world.level.chunk.ChunkGenerator;
import net.minecraft.world.level.chunk.ChunkStatus;
import net.minecraft.world.level.chunk.DataLayer;
import net.minecraft.world.level.chunk.LevelChunkSection;
import net.minecraft.world.level.chunk.LightChunkGetter;
import net.minecraft.world.level.chunk.ProtoChunk;
@@ -86,7 +94,12 @@ import net.minecraft.world.level.levelgen.blending.Blender;
import net.minecraft.world.level.levelgen.structure.StructureCheck;
import net.minecraft.world.level.levelgen.structure.StructureStart;
import net.minecraft.world.level.levelgen.structure.templatesystem.StructureManager;
import net.minecraft.world.level.lighting.BlockLightEngine;
import net.minecraft.world.level.lighting.LayerLightEngine;
import net.minecraft.world.level.lighting.LayerLightEventListener;
import net.minecraft.world.level.lighting.LevelLightEngine;
import net.minecraft.world.level.lighting.LightEventListener;
import net.minecraft.world.level.lighting.SkyLightEngine;
import net.minecraft.world.level.storage.WorldData;
/*
@@ -104,9 +117,10 @@ Lod Generation: 0.269023348s
*/
public final class WorldGenerationStep {
public static final boolean ENABLE_PERF_LOGGING = false;
public static final boolean ENABLE_PERF_LOGGING = true;
public static final boolean ENABLE_EVENT_LOGGING = false;
//TODO: Make this LightMode a config
//TODO: Make actual proper support for StarLight
public static final LightMode DEFAULT_LIGHTMODE = LightMode.Fancy;
//FIXME: Move this outside the WorldGenerationStep thingy
@@ -538,6 +552,7 @@ public final class WorldGenerationStep {
GridList<ChunkAccess> referencedChunks;
DistanceGenerationMode generationMode;
LightedWorldGenRegion region;
try {
int cx = e.pos.x;
int cy = e.pos.z;
@@ -627,7 +642,7 @@ public final class WorldGenerationStep {
subRange.forEach((chunk) -> {
((ProtoChunk) chunk).setLightEngine(region.getLightEngine());
if (region.lightMode == LightMode.Step) {
((WorldGenLightEngine)region.getLightEngine()).lightChunk(chunk, false);
((WorldGenLevelLightEngine)region.getLightEngine()).lightChunk(chunk, false);
}
});
stepStructureStart.generateGroup(e.tParam, region, subRange);
@@ -671,7 +686,7 @@ public final class WorldGenerationStep {
stepLight.generateGroup(region.getLightEngine(), subRange);
break;
case Step:
((WorldGenLightEngine)region.getLightEngine()).runUpdates();
((WorldGenLevelLightEngine)region.getLightEngine()).runUpdates();
break;
case Fast:
break;
@@ -948,7 +963,7 @@ public final class WorldGenerationStep {
public final class StepLight {
public final ChunkStatus STATUS = ChunkStatus.LIGHT;
public void generateGroup(LevelLightEngine lightEngine,
public void generateGroup(LightEventListener lightEngine,
GridList<ChunkAccess> chunks) {
//ArrayList<ChunkAccess> chunksToDo = new ArrayList<ChunkAccess>();
@@ -959,10 +974,13 @@ public final class WorldGenerationStep {
for (ChunkAccess chunk : chunks) {
try {
if (lightEngine instanceof WorldGenLightEngine) {
((WorldGenLightEngine)lightEngine).lightChunk(chunk, true);
if (lightEngine == null) {
chunk.setLightCorrect(true);
} else if (lightEngine instanceof WorldGenLevelLightEngine) {
((WorldGenLevelLightEngine)lightEngine).lightChunk(chunk, true);
} else if (lightEngine instanceof ThreadedLevelLightEngine) {
((ThreadedLevelLightEngine) lightEngine).lightChunk(chunk, true).join();
chunk.setLightCorrect(true);
} else {
assert(false);
}
@@ -979,7 +997,7 @@ public final class WorldGenerationStep {
}
public static class LightedWorldGenRegion extends WorldGenRegion {
final LevelLightEngine light;
final WorldGenLevelLightEngine light;
final LightMode lightMode;
final EmptyChunkGenerator generator;
Long2ObjectOpenHashMap<ChunkAccess> chunkMap = new Long2ObjectOpenHashMap<ChunkAccess>();
@@ -988,9 +1006,50 @@ public final class WorldGenerationStep {
super(serverLevel, list, chunkStatus, i);
this.lightMode = lightMode;
this.generator = generator;
light = lightMode==LightMode.StarLight ? serverLevel.getLightEngine() : new WorldGenLightEngine(new LightGetterAdaptor(this));
light = new WorldGenLevelLightEngine(new LightGetterAdaptor(this));
}
@Override
public boolean setBlock(BlockPos blockPos, BlockState blockState, int i, int j) {
if (!this.ensureCanWrite(blockPos)) {
return false;
}
ChunkAccess chunkAccess = this.getChunk(blockPos);
BlockState blockState2 = chunkAccess.setBlockState(blockPos, blockState, false);
if (blockState.hasBlockEntity()) {
if (chunkAccess.getStatus().getChunkType() == ChunkStatus.ChunkType.LEVELCHUNK) {
BlockEntity blockEntity = ((EntityBlock)((Object)blockState.getBlock())).newBlockEntity(blockPos, blockState);
if (blockEntity != null) {
chunkAccess.setBlockEntity(blockEntity);
} else {
chunkAccess.removeBlockEntity(blockPos);
}
} else {
CompoundTag compoundTag = new CompoundTag();
compoundTag.putInt("x", blockPos.getX());
compoundTag.putInt("y", blockPos.getY());
compoundTag.putInt("z", blockPos.getZ());
compoundTag.putString("id", "DUMMY");
chunkAccess.setBlockEntityNbt(compoundTag);
}
} else if (blockState2 != null && blockState2.hasBlockEntity()) {
chunkAccess.removeBlockEntity(blockPos);
}
if (blockState.hasPostProcess(this, blockPos)) {
this.getChunk(blockPos).markPosForPostprocessing(blockPos);
}
return true;
}
@Override
public boolean destroyBlock(BlockPos blockPos, boolean bl, @Nullable Entity entity, int i) {
BlockState blockState = this.getBlockState(blockPos);
if (blockState.isAir()) {
return false;
}
return this.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3, i);
}
@Override
public LevelLightEngine getLightEngine() {
return light;
@@ -998,8 +1057,9 @@ public final class WorldGenerationStep {
@Override
public int getBrightness(LightLayer lightLayer, BlockPos blockPos) {
if (lightMode != LightMode.Fast)
if (lightMode != LightMode.Fast) {
return light.getLayerListener(lightLayer).getLightValue(blockPos);
}
if (lightLayer == LightLayer.BLOCK) return 0;
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY()<=blockPos.getY()) ? getMaxLightLevel() : 0;
@@ -1007,8 +1067,9 @@ public final class WorldGenerationStep {
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
if (lightMode != LightMode.Fast)
if (lightMode != LightMode.Fast) {
return light.getRawBrightness(blockPos, i);
}
BlockPos p = super.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, blockPos);
return (p.getY()<=blockPos.getY()) ? getMaxLightLevel() : 0;
}
@@ -1025,7 +1086,7 @@ public final class WorldGenerationStep {
ChunkAccess chunk = chunkMap.get(ChunkPos.asLong(i, j));
if (chunk!=null) return chunk;
chunk = generator.generate(i, j);
if (chunk==null) throw new NullPointerException();
if (chunk==null) throw new NullPointerException("The provided generator should not return null!");
chunkMap.put(ChunkPos.asLong(i, j), chunk);
return chunk;
}
@@ -1034,9 +1095,11 @@ public final class WorldGenerationStep {
}
public static class LightGetterAdaptor implements LightChunkGetter {
public final WorldGenRegion genRegion;
public LightGetterAdaptor(WorldGenRegion genRegion) {
public final LightedWorldGenRegion genRegion;
final boolean shouldReturnNull;
public LightGetterAdaptor(LightedWorldGenRegion genRegion) {
this.genRegion = genRegion;
shouldReturnNull = genRegion.lightMode==LightMode.StarLight ? true : false;
}
@Override
public BlockGetter getChunkForLighting(int chunkX, int chunkZ) {
@@ -1045,13 +1108,115 @@ public final class WorldGenerationStep {
}
@Override
public BlockGetter getLevel() {
return shouldReturnNull ? null : genRegion;
}
public LevelHeightAccessor getLevelHeightAccessor() {
return genRegion;
}
}
public static class WorldGenLightEngine extends LevelLightEngine {
public WorldGenLightEngine(LightGetterAdaptor genRegion) {
super(genRegion, true, true);
}
public static class WorldGenLevelLightEngine extends LevelLightEngine {
public static final int MAX_SOURCE_LEVEL = 15;
public static final int LIGHT_SECTION_PADDING = 1;
protected final LevelHeightAccessor levelHeightAccessor;
@Nullable
public final LayerLightEngine<?, ?> blockEngine;
@Nullable
public final LayerLightEngine<?, ?> skyEngine;
public WorldGenLevelLightEngine(LightGetterAdaptor genRegion) {
super(genRegion, false, false);
this.levelHeightAccessor = genRegion.getLevelHeightAccessor();
this.blockEngine = new BlockLightEngine(genRegion);
this.skyEngine = new SkyLightEngine(genRegion);
}
@Override
public void checkBlock(BlockPos blockPos) {
if (this.blockEngine != null) {
this.blockEngine.checkBlock(blockPos);
}
if (this.skyEngine != null) {
this.skyEngine.checkBlock(blockPos);
}
}
@Override
public void onBlockEmissionIncrease(BlockPos blockPos, int i) {
if (this.blockEngine != null) {
this.blockEngine.onBlockEmissionIncrease(blockPos, i);
}
}
@Override
public boolean hasLightWork() {
if (this.skyEngine != null && this.skyEngine.hasLightWork()) {
return true;
}
return this.blockEngine != null && this.blockEngine.hasLightWork();
}
@Override
public int runUpdates(int i, boolean bl, boolean bl2) {
if (this.blockEngine != null && this.skyEngine != null) {
int j = i / 2;
int k = this.blockEngine.runUpdates(j, bl, bl2);
int l = i - j + k;
int m = this.skyEngine.runUpdates(l, bl, bl2);
if (k == 0 && m > 0) {
return this.blockEngine.runUpdates(m, bl, bl2);
}
return m;
}
if (this.blockEngine != null) {
return this.blockEngine.runUpdates(i, bl, bl2);
}
if (this.skyEngine != null) {
return this.skyEngine.runUpdates(i, bl, bl2);
}
return i;
}
@Override
public void updateSectionStatus(SectionPos sectionPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.updateSectionStatus(sectionPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.updateSectionStatus(sectionPos, bl);
}
}
@Override
public void enableLightSources(ChunkPos chunkPos, boolean bl) {
if (this.blockEngine != null) {
this.blockEngine.enableLightSources(chunkPos, bl);
}
if (this.skyEngine != null) {
this.skyEngine.enableLightSources(chunkPos, bl);
}
}
@Override
public LayerLightEventListener getLayerListener(LightLayer lightLayer) {
if (lightLayer == LightLayer.BLOCK) {
if (this.blockEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.blockEngine;
}
if (this.skyEngine == null) {
return LayerLightEventListener.DummyLightLayerEventListener.INSTANCE;
}
return this.skyEngine;
}
@Override
public int getRawBrightness(BlockPos blockPos, int i) {
int j = this.skyEngine == null ? 0 : this.skyEngine.getLightValue(blockPos) - i;
int k = this.blockEngine == null ? 0 : this.blockEngine.getLightValue(blockPos);
return Math.max(k, j);
}
public void lightChunk(ChunkAccess chunkAccess, boolean hasLightBlock) {
ChunkPos chunkPos = chunkAccess.getPos();
@@ -1062,20 +1227,45 @@ public final class WorldGenerationStep {
LevelChunkSection levelChunkSection = levelChunkSections[i];
if (levelChunkSection.hasOnlyAir()) continue;
int j = this.levelHeightAccessor.getSectionYFromSectionIndex(i);
super.updateSectionStatus(SectionPos.of(chunkPos, j), false);
updateSectionStatus(SectionPos.of(chunkPos, j), false);
}
super.enableLightSources(chunkPos, true);
enableLightSources(chunkPos, true);
if (hasLightBlock) {
chunkAccess.getLights().forEach(blockPos ->
super.onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
onBlockEmissionIncrease(blockPos, chunkAccess.getLightEmission(blockPos)));
}
chunkAccess.setLightCorrect(true);
runUpdates();
}
public void runUpdates() {
super.runUpdates(2147483647, true, true);
runUpdates(2147483647, true, true);
}
@Override
public String getDebugData(LightLayer lightLayer, SectionPos sectionPos) {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public void queueSectionData(LightLayer lightLayer, SectionPos sectionPos, @Nullable DataLayer dataLayer, boolean bl) {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public void retainData(ChunkPos chunkPos, boolean bl) {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getLightSectionCount() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMinLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
@Override
public int getMaxLightSection() {
throw new UnsupportedOperationException("This should never be used!");
}
}
+4 -4
View File
@@ -13,12 +13,12 @@ fabric_loader_version=0.12.12
fabric_api_version=0.44.0+1.18
# Fabric mods
modmenu_version=3.0.0
# starlight_version_fabric=3554912
starlight_version_fabric=3554912
sodium_version=mc1.18-0.4.0-alpha5
# iris_version=1.18.x-v1.1.4
# immersive_portals_version = v1.0.4-1.18
iris_version=1.18.x-v1.1.4
immersive_portals_version = v1.0.4-1.18
# Forge loader
forge_version=39.0.44
# Forge mods
# starlight_version_forge=3559934
starlight_version_forge=3559934