Fix incorrect unloaded chunk lighting

This commit is contained in:
James Seibel
2023-08-06 19:18:31 -05:00
parent df63dd1370
commit 38a7a837e7
2 changed files with 59 additions and 0 deletions
@@ -21,6 +21,7 @@ package com.seibel.distanthorizons.core.api.internal;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelLoadEvent;
import com.seibel.distanthorizons.api.methods.events.abstractEvents.DhApiLevelUnloadEvent;
import com.seibel.distanthorizons.core.generation.DhLightingEngine;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.coreapi.DependencyInjection.ApiEventInjector;
import com.seibel.distanthorizons.core.level.IDhLevel;
@@ -34,6 +35,9 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
import org.apache.logging.log4j.Logger;
import java.util.LinkedList;
import java.util.List;
/**
* This holds the methods that should be called by the host mod loader (Fabric,
* Forge, etc.). Specifically server events.
@@ -153,6 +157,32 @@ public class ServerApi
IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level);
if (dhLevel != null)
{
// Save or populate the chunk wrapper's lighting
// this is done so we don't have to worry about MC unloading the lighting data for this chunk
if (chunk.isLightCorrect())
{
try
{
chunk.bakeDhLightingUsingMcLightingEngine();
chunk.setUseDhLighting(true);
}
catch (IllegalStateException e)
{
LOGGER.warn(e.getMessage(), e);
}
}
else
{
// generate the chunk's lighting, ignoring neighbors.
// not a perfect solution, but should prevent chunks from having completely broken lighting
List<IChunkWrapper> nearbyChunkList = new LinkedList<>();
nearbyChunkList.add(chunk);
DhLightingEngine.INSTANCE.lightChunks(chunk, nearbyChunkList, level.hasSkyLight() ? 15 : 0);
chunk.setUseDhLighting(true);
}
dhLevel.updateChunkAsync(chunk);
}
}
@@ -53,6 +53,7 @@ public interface IChunkWrapper extends IBindable
long getLongChunkPos();
void setIsDhLightCorrect(boolean isDhLightCorrect);
void setUseDhLighting(boolean useDhLighting);
boolean isLightCorrect();
@@ -65,6 +66,34 @@ public interface IChunkWrapper extends IBindable
int getBlockLight(int relX, int relY, int relZ);
int getSkyLight(int relX, int relY, int relZ);
/**
* Populates DH's saved lighting using MC's lighting engine.
* This is generally done in cases where MC's lighting is correct now, but may not be later (like when a chunk is unloading).
*
* @throws IllegalStateException if the chunk's lighting isn't valid. This is done to prevent accidentally baking broken lighting.
*/
default void bakeDhLightingUsingMcLightingEngine() throws IllegalStateException
{
if (!this.isLightCorrect())
{
throw new IllegalStateException("Unable to bake lighting for for chunk ["+this.getChunkPos()+"], Minecraft lighting not valid.");
}
// get the lighting for every relative block pos
for (int relX = 0; relX < LodUtil.CHUNK_WIDTH; relX++)
{
for (int relZ = 0; relZ < LodUtil.CHUNK_WIDTH; relZ++)
{
for (int y = this.getMinBuildHeight(); y < this.getMaxBuildHeight(); y++)
{
this.setDhSkyLight(relX, y, relZ, this.getSkyLight(relX, y, relZ));
this.setDhBlockLight(relX, y, relZ, this.getBlockLight(relX, y, relZ));
}
}
}
}
List<DhBlockPos> getBlockLightPosList();