Skip to content

Commit

Permalink
LambDynamicLights v1.3.1: Fix issues with Sodium.
Browse files Browse the repository at this point in the history
  • Loading branch information
LambdAurora committed Sep 29, 2020
1 parent 3485a40 commit 31a3e08
Show file tree
Hide file tree
Showing 13 changed files with 167 additions and 49 deletions.
20 changes: 14 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,17 @@
- Added water-sensitive check for items and light sources.
- Added data item tag `#lambdynlights:water_sensitive` which lists every item which can't light up in the water.
- Added an option to enable/disable the feature
- Updated SpruceUI to v1.5.6 to fix latest snapshots issues.
- Added "early/WIP" compatibility with [Canvas Renderer](https://www.curseforge.com/minecraft/mc-mods/canvas-renderer).
- Updated [SpruceUI] to v1.5.6 to fix latest snapshots issues.
- Added "early/WIP" compatibility with [Canvas Renderer].
- Added a warning message about performance issues.
- Fixed a crash with Sodium rc7 with smooth lighting set to HIGH.
- Fixed a crash with [Sodium] rc7 with smooth lighting set to HIGH.

### v1.2.1

- Added TNT dynamic lighting.
- Added lighting options for TNT and Creepers.
- Added luminance value to Fire charge item.
- Updated SpruceUI to v1.5.8
- Updated [SpruceUI] to v1.5.8
- Fixed player dynamic lighting not getting tracked when changing dimensions.

### v1.2.2
Expand All @@ -53,9 +53,17 @@
- Added spectral arrow as item emitting light ([#17](https://github.com/LambdAurora/LambDynamicLights/pull/17)).
- Added dynamic lighting on glowing entities ([#17](https://github.com/LambdAurora/LambDynamicLights/pull/17)).
- Updated to Minecraft 1.16.2
- Updated [SpruceUI](https://github.com/LambdAurora/SpruceUI) to v1.6.2.
- Updated [SpruceUI] to v1.6.2.
- Fixed dynamic lighting update issues at chunk borders ([#12](https://github.com/LambdAurora/LambDynamicLights/issues/12)).
- Fixed water-sensitive items lighting up in water on dedicated servers. ([#3](https://github.com/LambdAurora/LambDynamicLights/issues/3))
- Added new JSON API to add item luminance and water-sensitivity through resource packs.
- Added `DynamicLightHandler#isWaterSensitive` to make some entities water-sensitive like the blaze.
- Fixed incompatibility with future Sodium versions. ([#6](https://github.com/LambdAurora/LambDynamicLights/issues/6))
- Fixed incompatibility with future [Sodium] versions. ([#6](https://github.com/LambdAurora/LambDynamicLights/issues/6))

## v1.3.1

- Fixed entity lighting issue with [Sodium] 0.1.0. ([#23](https://github.com/LambdAurora/LambDynamicLights/issues/23))

[SpruceUI]: https://github.com/LambdAurora/SpruceUI "SpruceUI page"
[Sodium]: https://www.curseforge.com/minecraft/mc-mods/sodium "Sodium CurseForge page"
[Canvas Renderer]: https://www.curseforge.com/minecraft/mc-mods/canvas-renderer "Canvas Renderer CurseForge page"
10 changes: 5 additions & 5 deletions HOW_DOES_IT_WORK.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ UpcraftLP method can be found here: https://gist.github.com/UpcraftLP/93db478535
AtomicStryker method can be found here: https://github.com/AtomicStryker/atomicstrykers-minecraft-mods/tree/1.14.3/DynamicLights

Both methods suffer from a "laggy" dynamic lighting, the way the light moves is too much tied to
the block positions as it only injects at luminance getters in `WorldChunk` or a lighting provider.
the block positions as it only injects at light level getters in `WorldChunk` or a lighting provider.
It will only provide the dynamic light value of the light source if the block position is the position
of the light source.

Expand All @@ -36,16 +36,16 @@ light sources, their distances and the luminance), if the dynamic value is highe
then we replace it.

This also means that we can't just do like the previous method and only give the source luminance but
we also have to calculate the surrounding luminance created by the dynamic light source in a specified
we also have to calculate the surrounding light level created by the dynamic light sources in a specified
range (which is 7.75 to limit chunk rebuilding to 8 chunks (which is still a lot)).

When getting the dynamic light value at the specified position, it has to be a `double` and not
an integer as the light value calculated with the range has to be precise.
an integer as the light level calculated within the range has to be precise.
To modify the lightmap with the dynamic light value, it has to be multiplied by 16.0 instead of
using a bitshift to preserve as much as possible the precision.

Dynamic light value at a specified position is calculated in a for-loop with all the dynamic light
sources, only the highest light value is kept. The light value is calculated as follow:
Dynamic light level at a specified position is calculated in a for-loop with all the dynamic light
sources, only the highest light level is kept. The light level is calculated as follow:

```java
// dist being the distance between the light source origin and the position where the
Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ dependencies {

modImplementation "io.github.prospector:modmenu:${project.modmenu_version}"
//modImplementation "grondag:canvas-mc116:1.0.+"
//modImplementation "me.jellysquid.mods:sodium:0.1.0+v8-SNAPSHOT"
modImplementation "com.github.jellysquid3:sodium-fabric:mc1.16.3-0.1.0"

shadow "com.electronwill.night-config:core:3.6.3"
shadow "com.electronwill.night-config:toml:3.6.3"
Expand Down
12 changes: 6 additions & 6 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ org.gradle.jvmargs=-Xmx1G

# Fabric Properties
# check these on https://fabricmc.net/use
minecraft_version=1.16.2
yarn_mappings=1.16.2+build.6
loader_version=0.9.1+build.205
minecraft_version=1.16.3
yarn_mappings=1.16.3+build.17
loader_version=0.9.3+build.207

# Mod Properties
mod_version = 1.3.0
mod_version = 1.3.1
maven_group = me.lambdaurora
archives_base_name = lambdynamiclights

# Dependencies
# currently not on the main fabric site, check on the maven: https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api
fabric_version=0.17.2+build.396-1.16
spruceui_version=1.6.2
fabric_version=0.20.2+build.402-1.16
spruceui_version=1.6.4
modmenu_version=1.14.6+build.31
38 changes: 19 additions & 19 deletions src/main/java/me/lambdaurora/lambdynlights/LambDynLights.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
* Represents the LambDynamicLights mod.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.3.1
* @since 1.0.0
*/
public class LambDynLights implements ClientModInitializer
Expand Down Expand Up @@ -129,7 +129,7 @@ public void updateAll(@NotNull WorldRenderer renderer)
*/
public int getLightmapWithDynamicLight(@NotNull BlockPos pos, int lightmap)
{
return this.getLightmapWithDynamicLight(this.getDynamicLuminance(pos), lightmap);
return this.getLightmapWithDynamicLight(this.getDynamicLightLevel(pos), lightmap);
}

/**
Expand All @@ -141,29 +141,29 @@ public int getLightmapWithDynamicLight(@NotNull BlockPos pos, int lightmap)
*/
public int getLightmapWithDynamicLight(@NotNull Entity entity, int lightmap)
{
int posLuminance = (int) this.getDynamicLuminance(entity.getBlockPos());
int posLightLevel = (int) this.getDynamicLightLevel(entity.getBlockPos());
int entityLuminance = ((DynamicLightSource) entity).getLuminance();

return this.getLightmapWithDynamicLight(Math.max(posLuminance, entityLuminance), lightmap);
return this.getLightmapWithDynamicLight(Math.max(posLightLevel, entityLuminance), lightmap);
}

/**
* Returns the lightmap with combined light levels.
*
* @param dynamicLuminance The dynamic light level.
* @param lightmap The vanilla lightmap.
* @param dynamicLightLevel The dynamic light level.
* @param lightmap The vanilla lightmap.
* @return The modified lightmap.
*/
public int getLightmapWithDynamicLight(double dynamicLuminance, int lightmap)
public int getLightmapWithDynamicLight(double dynamicLightLevel, int lightmap)
{
if (dynamicLuminance > 0) {
if (dynamicLightLevel > 0) {
// lightmap is (skyLevel << 20 | blockLevel << 4)

// Get vanilla block light level.
int blockLevel = LightmapTextureManager.getBlockLightCoordinates(lightmap);
if (dynamicLuminance > blockLevel) {
if (dynamicLightLevel > blockLevel) {
// Equivalent to a << 4 bitshift with a little quirk: this one ensure more precision (more decimals are saved).
int luminance = (int) (dynamicLuminance * 16.0);
int luminance = (int) (dynamicLightLevel * 16.0);
lightmap &= 0xfff00000;
lightmap |= luminance & 0x000fffff;
}
Expand All @@ -178,11 +178,11 @@ public int getLightmapWithDynamicLight(double dynamicLuminance, int lightmap)
* @param pos The position.
* @return The dynamic light level at the spec
*/
public double getDynamicLuminance(@NotNull BlockPos pos)
public double getDynamicLightLevel(@NotNull BlockPos pos)
{
double result = 0;
for (DynamicLightSource lightSource : this.dynamicLightSources) {
result = maxDynamicLuminance(pos, lightSource, result);
result = maxDynamicLightLevel(pos, lightSource, result);
}

return MathHelper.clamp(result, 0, 15);
Expand All @@ -191,12 +191,12 @@ public double getDynamicLuminance(@NotNull BlockPos pos)
/**
* Returns the dynamic light level generated by the light source at the specified position.
*
* @param pos The position.
* @param lightSource The light source.
* @param currentLuminance The current surrounding dynamic luminance.
* @param pos The position.
* @param lightSource The light source.
* @param currentLightLevel The current surrounding dynamic light level.
* @return The dynamic light level.
*/
public static double maxDynamicLuminance(@NotNull BlockPos pos, @NotNull DynamicLightSource lightSource, double currentLuminance)
public static double maxDynamicLightLevel(@NotNull BlockPos pos, @NotNull DynamicLightSource lightSource, double currentLightLevel)
{
int luminance = lightSource.getLuminance();
if (luminance > 0) {
Expand All @@ -211,12 +211,12 @@ public static double maxDynamicLuminance(@NotNull BlockPos pos, @NotNull Dynamic
if (distance <= MAX_RADIUS) {
double multiplier = 1.0 - distance / MAX_RADIUS;
double lightLevel = multiplier * (double) luminance;
if (lightLevel > currentLuminance) {
currentLuminance = lightLevel;
if (lightLevel > currentLightLevel) {
currentLightLevel = lightLevel;
}
}
}
return currentLuminance;
return currentLightLevel;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* Represents a utility class for compatibility.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.3.1
* @since 1.0.0
*/
public final class LambDynLightsCompat
Expand Down Expand Up @@ -50,4 +50,15 @@ public static boolean isSodiumInstalled()
{
return FabricLoader.getInstance().isModLoaded("sodium");
}

/**
* Returns whether Sodium 0.1.0 is installed.
*
* @return True if Sodium 0.1.0 is installed, else false.
*/
public static boolean isSodium010Installed()
{
return FabricLoader.getInstance().getModContainer("sodium").map(mod -> mod.getMetadata().getVersion().getFriendlyString().equalsIgnoreCase("0.1.0"))
.orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
* LambDynamicLights mixin plugin for conditional mixins.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.3.1
* @since 1.0.0
*/
public class LambDynLightsMixinPlugin implements IMixinConfigPlugin
Expand All @@ -37,6 +37,7 @@ public LambDynLightsMixinPlugin()
boolean canvasInstalled = LambDynLightsCompat.isCanvasInstalled();
boolean sodiumInstalled = LambDynLightsCompat.isSodiumInstalled();
this.conditionalMixins.put("me.lambdaurora.lambdynlights.mixin.WorldRendererMixin", !sodiumInstalled && !canvasInstalled);
this.conditionalMixins.put("me.lambdaurora.lambdynlights.mixin.EntityLighterMixin", LambDynLightsCompat.isSodium010Installed());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,20 @@
import net.minecraft.block.Blocks;
import net.minecraft.item.BlockItem;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.Items;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.Registry;
import org.jetbrains.annotations.NotNull;

import java.util.Objects;
import java.util.Optional;

/**
* Represents an item light source.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.3.1
* @since 1.3.0
*/
public class ItemLightSource
Expand All @@ -50,14 +52,39 @@ public ItemLightSource(@NotNull Identifier id, @NotNull Item item, int luminance
this.waterSensitive = waterSensitive;
}

public int getLuminance(boolean submergedInWater)
/**
* Gets the luminance of the item.
*
* @param stack The item stack.
* @param submergedInWater True if submerged in water, else false.
* @return The luminance value between 0 and 15.
*/
public int getLuminance(@NotNull ItemStack stack, boolean submergedInWater)
{
if (this.waterSensitive && LambDynLights.get().config.hasWaterSensitiveCheck() && submergedInWater)
return 0; // Don't emit light with water sensitive items while submerged in water.

return this.luminance;
}

@Override
public boolean equals(Object o)
{
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ItemLightSource that = (ItemLightSource) o;
return luminance == that.luminance &&
waterSensitive == that.waterSensitive &&
Objects.equals(id, that.id) &&
Objects.equals(item, that.item);
}

@Override
public int hashCode()
{
return Objects.hash(id, item, luminance, waterSensitive);
}

@Override
public String toString()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,13 @@
* Represents an item light sources manager.
*
* @author LambdAurora
* @version 1.3.0
* @version 1.3.1
* @since 1.3.0
*/
public final class ItemLightSources
{
private static final List<ItemLightSource> ITEM_LIGHT_SOURCES = new ArrayList<>();
private static final List<ItemLightSource> ITEM_LIGHT_SOURCES = new ArrayList<>();
private static final List<ItemLightSource> STATIC_ITEM_LIGHT_SOURCES = new ArrayList<>();

/**
* Loads the item light source data from resource pack.
Expand All @@ -47,6 +48,8 @@ public static void load(@NotNull ResourceManager resourceManager)
ITEM_LIGHT_SOURCES.clear();

resourceManager.findResources("dynamiclights/item", path -> path.endsWith(".json")).forEach(id -> load(resourceManager, id));

ITEM_LIGHT_SOURCES.addAll(STATIC_ITEM_LIGHT_SOURCES);
}

private static void load(@NotNull ResourceManager resourceManager, @NotNull Identifier resourceId)
Expand All @@ -61,7 +64,10 @@ private static void load(@NotNull ResourceManager resourceManager, @NotNull Iden
return;
}

register(result.get());
ItemLightSource data = result.get();
if (STATIC_ITEM_LIGHT_SOURCES.contains(data))
return;
register(data);
} catch (IOException | IllegalStateException e) {
LambDynLights.get().warn("Failed to load item light source \"" + id + "\".");
}
Expand All @@ -72,7 +78,7 @@ private static void load(@NotNull ResourceManager resourceManager, @NotNull Iden
*
* @param data The item light source data.
*/
public static void register(@NotNull ItemLightSource data)
private static void register(@NotNull ItemLightSource data)
{
for (ItemLightSource other : ITEM_LIGHT_SOURCES) {
if (other.item == data.item) {
Expand All @@ -85,6 +91,24 @@ public static void register(@NotNull ItemLightSource data)
ITEM_LIGHT_SOURCES.add(data);
}

/**
* Registers an item light source data.
*
* @param data The item light source data.
*/
public static void registerItemLightSource(@NotNull ItemLightSource data)
{
for (ItemLightSource other : STATIC_ITEM_LIGHT_SOURCES) {
if (other.item == data.item) {
LambDynLights.get().warn("Failed to register item light source \"" + data.id + "\", duplicates item \""
+ Registry.ITEM.getId(data.item) + "\" found in \"" + other.id + "\".");
return;
}
}

STATIC_ITEM_LIGHT_SOURCES.add(data);
}

/**
* Returns the luminance of the item in the stack.
*
Expand All @@ -96,7 +120,7 @@ public static int getLuminance(@NotNull ItemStack stack, boolean submergedInWate
{
for (ItemLightSource data : ITEM_LIGHT_SOURCES) {
if (data.item == stack.getItem()) {
return data.getLuminance(submergedInWater);
return data.getLuminance(stack, submergedInWater);
}
}
if (stack.getItem() instanceof BlockItem)
Expand Down
Loading

0 comments on commit 31a3e08

Please sign in to comment.