From be6aa16e74b3df7c9851c238c062837410e80484 Mon Sep 17 00:00:00 2001 From: LambdAurora Date: Sat, 30 Nov 2024 00:24:00 +0100 Subject: [PATCH] Add support for Trinkets and Accessories. --- CHANGELOG.md | 4 ++ build.gradle.kts | 9 +++ .../kotlin/lambdynamiclights/Constants.kt | 2 +- gradle/libs.versions.toml | 4 ++ .../lambdynlights/LambDynLights.java | 25 +++++++ .../compat/AccessoriesCompat.java | 43 ++++++++++++ .../lambdynlights/compat/CompatLayer.java | 66 +++++++++++++++++++ .../lambdynlights/compat/TrinketsCompat.java | 43 ++++++++++++ 8 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 src/main/java/dev/lambdaurora/lambdynlights/compat/AccessoriesCompat.java create mode 100644 src/main/java/dev/lambdaurora/lambdynlights/compat/CompatLayer.java create mode 100644 src/main/java/dev/lambdaurora/lambdynlights/compat/TrinketsCompat.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 43012059..ad1415ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -216,6 +216,10 @@ - Fixed item frames and other "block-attached" entities not ticking properly on the integrated server. +### 3.1.4 + +- Added support for Trinkets and Accessories. + [SpruceUI]: https://github.com/LambdAurora/SpruceUI "SpruceUI page" [pridelib]: https://github.com/Queerbric/pridelib "Pridelib page" [Sodium]: https://modrinth.com/mod/sodium "Sodium Modrinth page" diff --git a/build.gradle.kts b/build.gradle.kts index 4a4f2e18..e1eb0c1b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,6 +33,11 @@ repositories { name = "ParchmentMC" url = uri("https://maven.parchmentmc.org") } + maven { + name = "Ladysnake Libs" + url = uri("https://maven.ladysnake.org/releases") + } + maven { url = uri("https://maven.wispforest.io/releases") } exclusiveContent { forRepository { maven { @@ -66,6 +71,10 @@ dependencies { this.isTransitive = false } + // Mod compatibility + modCompileOnly(libs.trinkets) + modCompileOnly(libs.accessories) + modRuntimeOnly(libs.sodium) shadow(project(":api", configuration = "namedElements")) { diff --git a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt index b46bcb6a..f96e6220 100644 --- a/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt +++ b/build_logic/src/main/kotlin/lambdynamiclights/Constants.kt @@ -5,7 +5,7 @@ import org.gradle.accessors.dm.LibrariesForLibs object Constants { const val GROUP = "dev.lambdaurora" const val NAME = "lambdynamiclights" - const val VERSION = "3.1.3" + const val VERSION = "3.1.4" const val JAVA_VERSION = 21 private var minecraftVersion: String? = null diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b14c1371..9059022e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -10,6 +10,8 @@ yumi-commons = "1.0.0-alpha.1" spruceui = "5.1.0+1.21" pridelib = "1.2.1+1.21" modmenu = "11.0.1" +trinkets = "3.10.0" +accessories = "1.1.0-beta.16+1.21.1" sodium = "mc1.21-0.5.9" # Configuration @@ -32,6 +34,8 @@ yumi-commons-event = { module = "dev.yumi.commons:yumi-commons-event", version.r spruceui = { module = "dev.lambdaurora:spruceui", version.ref = "spruceui" } pridelib = { module = "io.github.queerbric:pridelib", version.ref = "pridelib" } modmenu = { module = "com.terraformersmc:modmenu", version.ref = "modmenu" } +trinkets = { module = "dev.emi:trinkets", version.ref = "trinkets" } +accessories = { module = "io.wispforest:accessories-fabric", version.ref = "accessories" } sodium = { module = "maven.modrinth:sodium", version.ref = "sodium" } # Configuration diff --git a/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java b/src/main/java/dev/lambdaurora/lambdynlights/LambDynLights.java index f6ad28ea..00259a62 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.DynamicLightHandlers; import dev.lambdaurora.lambdynlights.api.DynamicLightsInitializer; +import dev.lambdaurora.lambdynlights.compat.CompatLayer; import dev.lambdaurora.lambdynlights.engine.DynamicLightingEngine; import dev.lambdaurora.lambdynlights.resource.item.ItemLightSources; import dev.yumi.commons.event.EventManager; @@ -347,6 +348,20 @@ public static void warn(Logger logger, String msg, Object... args) { logger.warn(msg, args); } + /** + * Logs an error message. + * + * @param logger the logger to use + * @param msg the message to log + */ + public static void error(Logger logger, String msg, Object... args) { + if (!FabricLoader.getInstance().isDevelopmentEnvironment()) { + msg = "[LambDynLights] " + msg; + } + + logger.error(msg, args); + } + /** * Schedules a chunk rebuild at the specified chunk position. * @@ -423,6 +438,16 @@ public static int getLivingEntityLuminanceFromItems(LivingEntity entity) { luminance = Math.max(luminance, LambDynLights.getLuminanceFromItemStack(equipped, submergedInFluid)); } + if (luminance < 15) { + for (var compat : CompatLayer.LAYERS) { + luminance = Math.max(luminance, compat.getLivingEntityLuminanceFromItems(entity, submergedInFluid)); + + if (luminance >= 15) { + break; + } + } + } + return luminance; } diff --git a/src/main/java/dev/lambdaurora/lambdynlights/compat/AccessoriesCompat.java b/src/main/java/dev/lambdaurora/lambdynlights/compat/AccessoriesCompat.java new file mode 100644 index 00000000..1d6d0241 --- /dev/null +++ b/src/main/java/dev/lambdaurora/lambdynlights/compat/AccessoriesCompat.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the Lambda License. For more information, + * see the LICENSE file. + */ + +package dev.lambdaurora.lambdynlights.compat; + +import dev.lambdaurora.lambdynlights.LambDynLights; +import io.wispforest.accessories.api.AccessoriesCapability; +import net.minecraft.world.entity.LivingEntity; + +/** + * Represents the Accessories compatibility layer. + * + * @author LambdAurora + * @version 3.1.4 + * @since 3.1.4 + */ +final class AccessoriesCompat implements CompatLayer { + @Override + public int getLivingEntityLuminanceFromItems(LivingEntity entity, boolean submergedInWater) { + int luminance = 0; + var component = AccessoriesCapability.get(entity); + + if (component != null) { + for (var equipped : component.getAllEquipped()) { + if (!equipped.stack().isEmpty()) { + luminance = Math.max(luminance, LambDynLights.getLuminanceFromItemStack(equipped.stack(), submergedInWater)); + + if (luminance >= 15) { + break; + } + } + } + } + + return luminance; + } +} diff --git a/src/main/java/dev/lambdaurora/lambdynlights/compat/CompatLayer.java b/src/main/java/dev/lambdaurora/lambdynlights/compat/CompatLayer.java new file mode 100644 index 00000000..9bff917e --- /dev/null +++ b/src/main/java/dev/lambdaurora/lambdynlights/compat/CompatLayer.java @@ -0,0 +1,66 @@ +/* + * Copyright © 2024 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the Lambda License. For more information, + * see the LICENSE file. + */ + +package dev.lambdaurora.lambdynlights.compat; + +import dev.lambdaurora.lambdynlights.LambDynLights; +import net.fabricmc.loader.api.FabricLoader; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.Range; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +/** + * Represents a compatibility layer with another mod. + * + * @author LambdAurora + * @version 3.1.4 + * @since 3.1.4 + */ +public interface CompatLayer { + Logger LOGGER = LoggerFactory.getLogger("LambDynamicLights|CompatLayer"); + + /** + * Loaded compatibility layers. + */ + List LAYERS = initLayers(); + + /** + * Gets the luminance of a living entity from its equipped items. + * + * @param entity the living entity for which to get the luminance from + * @param submergedInWater {@code true} if the entity is submerged in water, or {@code false} otherwise + * @return the luminance of a living entity from its equipped items + */ + @Range(from = 0, to = 15) + int getLivingEntityLuminanceFromItems(LivingEntity entity, boolean submergedInWater); + + private static List initLayers() { + var layers = new ArrayList(); + + try { + if (FabricLoader.getInstance().isModLoaded("accessories")) { + layers.add(new AccessoriesCompat()); + } else if (FabricLoader.getInstance().isModLoaded("trinkets")) { + layers.add(new TrinketsCompat()); + } + } catch (LinkageError e) { + LambDynLights.error( + LOGGER, + "Could not load a compatibility layer: THIS IS VERY WRONG, PLEASE REPORT THIS ERROR TO LAMBDYNAMICLIGHTS' AUTHOR ASAP.", + e + ); + } + + return layers; + } +} diff --git a/src/main/java/dev/lambdaurora/lambdynlights/compat/TrinketsCompat.java b/src/main/java/dev/lambdaurora/lambdynlights/compat/TrinketsCompat.java new file mode 100644 index 00000000..ea786075 --- /dev/null +++ b/src/main/java/dev/lambdaurora/lambdynlights/compat/TrinketsCompat.java @@ -0,0 +1,43 @@ +/* + * Copyright © 2024 LambdAurora + * + * This file is part of LambDynamicLights. + * + * Licensed under the Lambda License. For more information, + * see the LICENSE file. + */ + +package dev.lambdaurora.lambdynlights.compat; + +import dev.emi.trinkets.api.TrinketsApi; +import dev.lambdaurora.lambdynlights.LambDynLights; +import net.minecraft.world.entity.LivingEntity; + +/** + * Represents the Trinkets compatibility layer. + * + * @author LambdAurora + * @version 3.1.4 + * @since 3.1.4 + */ +final class TrinketsCompat implements CompatLayer { + @Override + public int getLivingEntityLuminanceFromItems(LivingEntity entity, boolean submergedInWater) { + int luminance = 0; + var component = TrinketsApi.getTrinketComponent(entity); + + if (component.isPresent()) { + for (var equipped : component.get().getAllEquipped()) { + if (!equipped.getB().isEmpty()) { + luminance = Math.max(luminance, LambDynLights.getLuminanceFromItemStack(equipped.getB(), submergedInWater)); + + if (luminance >= 15) { + break; + } + } + } + } + + return luminance; + } +}