diff --git a/CHANGELOG.md b/CHANGELOG.md index f4280dc4..c4da47bf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -280,6 +280,7 @@ - Added Malay and Malay (Jawi) translations ([#256](https://github.com/LambdAurora/LambDynamicLights/pull/256)). - Fixed Upside-down English translations ([#257](https://github.com/LambdAurora/LambDynamicLights/pull/257)). +- Fixed custom dynamic light sources sometimes not updating previously lit chunks. [SpruceUI]: https://github.com/LambdAurora/SpruceUI "SpruceUI page" [pridelib]: https://github.com/Queerbric/pridelib "Pridelib page" diff --git a/api/src/main/java/dev/lambdaurora/lambdynlights/api/behavior/DynamicLightBehavior.java b/api/src/main/java/dev/lambdaurora/lambdynlights/api/behavior/DynamicLightBehavior.java index 6124c37f..bbfb5039 100644 --- a/api/src/main/java/dev/lambdaurora/lambdynlights/api/behavior/DynamicLightBehavior.java +++ b/api/src/main/java/dev/lambdaurora/lambdynlights/api/behavior/DynamicLightBehavior.java @@ -19,7 +19,7 @@ * Each dynamic lighting behavior have a way to give a light level at a given position, a bounding box, and a way to check for changes. * * @author LambdAurora, Akarys - * @version 4.0.0 + * @version 4.0.1 * @since 4.0.0 */ public interface DynamicLightBehavior { @@ -38,7 +38,7 @@ public interface DynamicLightBehavior { * double dz = pos.getZ() - this.z + 0.5; * * double distanceSquared = dx * dx + dy * dy + dz * dz; - * return luminance - Math.sqrt(distanceSquared) * falloffRatio; + * return Math.max(luminance - Math.sqrt(distanceSquared) * falloffRatio, 0.0); * } * * @@ -81,15 +81,15 @@ default boolean isRemoved() { /** * Represents the bounding box of a dynamic lighting behavior. + * + * @param startX the starting X-coordinate of this bounding box + * @param startY the starting Y-coordinate of this bounding box + * @param startZ the starting Z-coordinate of this bounding box + * @param endX the ending X-coordinate of this bounding box + * @param endY the ending Y-coordinate of this bounding box + * @param endZ the ending Z-coordinate of this bounding box */ - class BoundingBox { - int startX; - int startY; - int startZ; - int endX; - int endY; - int endZ; - + record BoundingBox(int startX, int startY, int startZ, int endX, int endY, int endZ) { public BoundingBox( int startX, int startY, @@ -105,47 +105,5 @@ public BoundingBox( this.endY = Math.max(startY, endY); this.endZ = Math.max(startZ, endZ); } - - /** - * {@return the starting X-coordinate of this bounding box} - */ - public int startX() { - return this.startX; - } - - /** - * {@return the starting Y-coordinate of this bounding box} - */ - public int startY() { - return this.startY; - } - - /** - * {@return the starting Z-coordinate of this bounding box} - */ - public int startZ() { - return this.startZ; - } - - /** - * {@return the ending X-coordinate of this bounding box} - */ - public int endX() { - return this.endX; - } - - /** - * {@return the ending Y-coordinate of this bounding box} - */ - public int endY() { - return this.endY; - } - - /** - * {@return the ending Z-coordinate of this bounding box} - */ - public int endZ() { - return this.endZ; - } } } diff --git a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt index 0d8ff8a4..461bbc43 100644 --- a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt +++ b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt @@ -7,7 +7,7 @@ object Constants { const val NAME = "lambdynamiclights" const val NAMESPACE = "lambdynlights" const val PRETTY_NAME = "LambDynamicLights" - const val VERSION = "4.0.0" + const val VERSION = "4.0.1" const val JAVA_VERSION = 21 const val DESCRIPTION = "The most feature-complete dynamic lighting mod for Fabric." diff --git a/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java b/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java index b7c20404..80b1dd23 100644 --- a/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java +++ b/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java @@ -12,6 +12,7 @@ import dev.lambdaurora.lambdynlights.accessor.WorldRendererAccessor; import dev.lambdaurora.lambdynlights.api.DynamicLightsContext; import dev.lambdaurora.lambdynlights.api.DynamicLightsInitializer; +import dev.lambdaurora.lambdynlights.api.behavior.DynamicLightBehavior; import dev.lambdaurora.lambdynlights.api.behavior.DynamicLightBehaviorManager; import dev.lambdaurora.lambdynlights.api.entity.EntityLightSourceManager; import dev.lambdaurora.lambdynlights.api.item.ItemLightSourceManager; @@ -67,7 +68,7 @@ * Represents the LambDynamicLights mod. * * @author LambdAurora - * @version 4.0.0 + * @version 4.0.1 * @since 1.0.0 */ @ApiStatus.Internal @@ -149,7 +150,9 @@ public void onInitializeClient() { var lightSource = it.next(); // In case of light sources controlled by a DynamicLightBehavior, they might require polling to be removed. - if (lightSource instanceof DeferredDynamicLightSource(var behavior)) { + if (lightSource instanceof DeferredDynamicLightSource deferred) { + DynamicLightBehavior behavior = deferred.behavior(); + if (behavior.isRemoved()) { this.toClear.add(lightSource); it.remove(); diff --git a/src/main/java/dev/lambdaurora/lambdynlights/engine/DynamicLightBehaviorSources.java b/src/main/java/dev/lambdaurora/lambdynlights/engine/DynamicLightBehaviorSources.java index 082e86ae..b727017b 100644 --- a/src/main/java/dev/lambdaurora/lambdynlights/engine/DynamicLightBehaviorSources.java +++ b/src/main/java/dev/lambdaurora/lambdynlights/engine/DynamicLightBehaviorSources.java @@ -19,7 +19,7 @@ * Represents the dynamic lighting behavior manager implementation. * * @author LambdAurora, Akarys - * @version 4.0.0 + * @version 4.0.1 * @since 4.0.0 */ public final class DynamicLightBehaviorSources implements DynamicLightBehaviorManager { @@ -38,8 +38,6 @@ public void add(@NotNull DynamicLightBehavior source) { public boolean remove(DynamicLightBehavior source) { if (source == null) return false; - return this.mod.removeLightSources(other -> other instanceof DeferredDynamicLightSource(DynamicLightBehavior otherBehavior) - && otherBehavior == source - ); + return this.mod.removeLightSources(other -> other instanceof DeferredDynamicLightSource deferred && deferred.behavior() == source); } } diff --git a/src/main/java/dev/lambdaurora/lambdynlights/engine/source/DeferredDynamicLightSource.java b/src/main/java/dev/lambdaurora/lambdynlights/engine/source/DeferredDynamicLightSource.java index 2ab8d19a..0f050fcc 100644 --- a/src/main/java/dev/lambdaurora/lambdynlights/engine/source/DeferredDynamicLightSource.java +++ b/src/main/java/dev/lambdaurora/lambdynlights/engine/source/DeferredDynamicLightSource.java @@ -25,10 +25,22 @@ * Represents a dynamic light source which is deferred to a {@link DynamicLightBehavior}. * * @author LambdAurora, Akarys - * @version 4.0.0 + * @version 4.0.1 * @since 4.0.0 */ -public record DeferredDynamicLightSource(DynamicLightBehavior behavior) implements DynamicLightSource { +public final class DeferredDynamicLightSource implements DynamicLightSource { + private final DynamicLightBehavior behavior; + private DynamicLightBehavior.BoundingBox previousBoundingBox; + + public DeferredDynamicLightSource(DynamicLightBehavior behavior) { + this.behavior = behavior; + this.previousBoundingBox = null; + } + + public DynamicLightBehavior behavior() { + return this.behavior; + } + @Override public Stream splitIntoDynamicLightEntries() { DynamicLightBehavior.BoundingBox boundingBox = this.behavior.getBoundingBox(); @@ -60,6 +72,17 @@ public LongSet getDynamicLightChunksToRebuild(boolean forced) { var chunks = new LongOpenHashSet(); + addBoundingBoxToChunksSet(chunks, boundingBox); + if (this.previousBoundingBox != null) { + addBoundingBoxToChunksSet(chunks, this.previousBoundingBox); + } + + this.previousBoundingBox = boundingBox; + + return chunks; + } + + private static void addBoundingBoxToChunksSet(LongSet set, DynamicLightBehavior.BoundingBox boundingBox) { int chunkStartX = getStartChunk(boundingBox.startX()); int chunkStartY = getStartChunk(boundingBox.startY()); int chunkStartZ = getStartChunk(boundingBox.startZ()); @@ -70,12 +93,10 @@ public LongSet getDynamicLightChunksToRebuild(boolean forced) { for (int x = chunkStartX; x <= chunkEndX; x++) { for (int y = chunkStartY; y <= chunkEndY; y++) { for (int z = chunkStartZ; z <= chunkEndZ; z++) { - chunks.add(ChunkSectionPos.asLong(x, y, z)); + set.add(ChunkSectionPos.asLong(x, y, z)); } } } - - return chunks; } private static int getStartChunk(int blockPos) {