diff options
-rw-r--r-- | build.gradle.kts | 12 | ||||
-rw-r--r-- | src/compat/explosiveEnhancement/java/ExplosiveEnhancementSpawner.kt | 17 | ||||
-rw-r--r-- | src/main/kotlin/features/fixes/CompatibliltyFeatures.kt | 70 | ||||
-rw-r--r-- | src/main/kotlin/util/compatloader/CompatLoader.kt | 47 |
4 files changed, 101 insertions, 45 deletions
diff --git a/build.gradle.kts b/build.gradle.kts index 20b077c..cca7fda 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -154,10 +154,6 @@ val SourceSet.modImplementationConfigurationName loom.remapConfigurations.find { it.targetConfigurationName.get() == this.implementationConfigurationName }!!.sourceConfiguration -val configuredSourceSet = createIsolatedSourceSet("configured") -val sodiumSourceSet = createIsolatedSourceSet("sodium") -val citResewnSourceSet = createIsolatedSourceSet("citresewn") -val yaclSourceSet = createIsolatedSourceSet("yacl") val shadowMe by configurations.creating { exclude(group = "org.jetbrains.kotlin") @@ -182,6 +178,12 @@ val nonModImplentation by configurations.creating { } +val configuredSourceSet = createIsolatedSourceSet("configured") +val sodiumSourceSet = createIsolatedSourceSet("sodium") +val citResewnSourceSet = createIsolatedSourceSet("citresewn") +val yaclSourceSet = createIsolatedSourceSet("yacl") +val explosiveEnhancementSourceSet = createIsolatedSourceSet("explosiveEnhancement") + dependencies { // Minecraft dependencies "minecraft"(libs.minecraft) @@ -196,7 +198,7 @@ dependencies { modImplementation(libs.modmenu) modImplementation(libs.moulconfig) modImplementation(libs.manninghamMills) - modCompileOnly(libs.explosiveenhancement) + (explosiveEnhancementSourceSet.modImplementationConfigurationName)(libs.explosiveenhancement) modImplementation(libs.hypixelmodapi) include(libs.hypixelmodapi.fabric) compileOnly(project(":javaplugin")) diff --git a/src/compat/explosiveEnhancement/java/ExplosiveEnhancementSpawner.kt b/src/compat/explosiveEnhancement/java/ExplosiveEnhancementSpawner.kt new file mode 100644 index 0000000..caf16a5 --- /dev/null +++ b/src/compat/explosiveEnhancement/java/ExplosiveEnhancementSpawner.kt @@ -0,0 +1,17 @@ +package moe.nea.firmament.compat.explosiveenhancement + +import com.google.auto.service.AutoService +import net.superkat.explosiveenhancement.api.ExplosiveApi +import net.minecraft.util.math.Vec3d +import moe.nea.firmament.features.fixes.CompatibliltyFeatures +import moe.nea.firmament.features.fixes.CompatibliltyFeatures.TConfig +import moe.nea.firmament.util.MC +import moe.nea.firmament.util.compatloader.CompatLoader + +@AutoService(CompatibliltyFeatures.ExplosiveApiWrapper::class) +@CompatLoader.RequireMod("explosiveenhancement") +class ExplosiveEnhancementSpawner : CompatibliltyFeatures.ExplosiveApiWrapper { + override fun spawnParticle(vec3d: Vec3d, power: Float) { + ExplosiveApi.spawnParticles(MC.world, vec3d.x, vec3d.y, vec3d.z, TConfig.explosionSize / 10F) + } +} diff --git a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt index fa9cdda..76f6ed4 100644 --- a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt +++ b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt @@ -1,51 +1,41 @@ - - package moe.nea.firmament.features.fixes -import net.fabricmc.loader.api.FabricLoader -import net.superkat.explosiveenhancement.api.ExplosiveApi import net.minecraft.particle.ParticleTypes import net.minecraft.util.math.Vec3d import moe.nea.firmament.annotations.Subscribe import moe.nea.firmament.events.ParticleSpawnEvent import moe.nea.firmament.features.FirmamentFeature import moe.nea.firmament.gui.config.ManagedConfig -import moe.nea.firmament.util.MC +import moe.nea.firmament.util.compatloader.CompatLoader object CompatibliltyFeatures : FirmamentFeature { - override val identifier: String - get() = "compatibility" - - object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { - val enhancedExplosions by toggle("explosion-enabled") { false } - val explosionSize by integer("explosion-power", 10, 50) { 1 } - } - - override val config: ManagedConfig? - get() = TConfig - - interface ExplosiveApiWrapper { - fun spawnParticle(vec3d: Vec3d, power: Float) - } - - class ExplosiveApiWrapperImpl : ExplosiveApiWrapper { - override fun spawnParticle(vec3d: Vec3d, power: Float) { - ExplosiveApi.spawnParticles(MC.world, vec3d.x, vec3d.y, vec3d.z, TConfig.explosionSize / 10F) - } - } - - val explosiveApiWrapper = if (FabricLoader.getInstance().isModLoaded("explosiveenhancement")) { - ExplosiveApiWrapperImpl() - } else null - - @Subscribe - fun onExplosion(it: ParticleSpawnEvent) { - if (TConfig.enhancedExplosions && - it.particleEffect.type == ParticleTypes.EXPLOSION_EMITTER && - explosiveApiWrapper != null - ) { - it.cancel() - explosiveApiWrapper.spawnParticle(it.position, 2F) - } - } + override val identifier: String + get() = "compatibility" + + object TConfig : ManagedConfig(identifier, Category.INTEGRATIONS) { + val enhancedExplosions by toggle("explosion-enabled") { false } + val explosionSize by integer("explosion-power", 10, 50) { 1 } + } + + override val config: ManagedConfig? + get() = TConfig + + interface ExplosiveApiWrapper { + fun spawnParticle(vec3d: Vec3d, power: Float) + + companion object : CompatLoader<ExplosiveApiWrapper>(ExplosiveApiWrapper::class.java) + } + + private val explosiveApiWrapper = ExplosiveApiWrapper.singleInstance + + @Subscribe + fun onExplosion(it: ParticleSpawnEvent) { + if (TConfig.enhancedExplosions && + it.particleEffect.type == ParticleTypes.EXPLOSION_EMITTER && + explosiveApiWrapper != null + ) { + it.cancel() + explosiveApiWrapper.spawnParticle(it.position, 2F) + } + } } diff --git a/src/main/kotlin/util/compatloader/CompatLoader.kt b/src/main/kotlin/util/compatloader/CompatLoader.kt new file mode 100644 index 0000000..c5d45bc --- /dev/null +++ b/src/main/kotlin/util/compatloader/CompatLoader.kt @@ -0,0 +1,47 @@ +package moe.nea.firmament.util.compatloader + +import java.util.ServiceLoader +import net.fabricmc.loader.api.FabricLoader +import kotlin.streams.asSequence +import moe.nea.firmament.Firmament + +abstract class CompatLoader<T : Any>(val kClass: Class<T>) { + val loader: ServiceLoader<T> = ServiceLoader.load(kClass) + val allValidInstances by lazy { + loader.reload() + loader.stream() + .asSequence() + .filter { provider -> + runCatching { + shouldLoad(provider.type()) + }.getOrElse { + Firmament.logger.error("Could not determine whether to load a ${kClass.name} subclass", it) + false + } + } + .mapNotNull { provider -> + runCatching { + provider.get() + }.getOrElse { + Firmament.logger.error( + "Could not load desired instance ${provider.type().name} for ${kClass.name}", + it) + null + } + } + .toList() + } + val singleInstance by lazy { allValidInstances.singleOrNull() } + + open fun shouldLoad(type: Class<out T>): Boolean { + return checkRequiredModsPresent(type) + } + + fun checkRequiredModsPresent(type: Class<*>): Boolean { + val requiredMods = type.getAnnotationsByType(RequireMod::class.java) + return requiredMods.all { FabricLoader.getInstance().isModLoaded(it.modId) } + } + + @Repeatable + annotation class RequireMod(val modId: String) +} |