Integrate ClothConfig for Forge
This commit is contained in:
@@ -6,9 +6,10 @@ plugins {
|
|||||||
apply(plugin = "org.spongepowered.mixin")
|
apply(plugin = "org.spongepowered.mixin")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven("http://files.minecraftforge.net/maven")
|
maven("https://files.minecraftforge.net/maven")
|
||||||
maven("https://repo.spongepowered.org/maven")
|
maven("https://repo.spongepowered.org/maven")
|
||||||
maven("https://minecraft.curseforge.com/api/maven")
|
maven("https://minecraft.curseforge.com/api/maven")
|
||||||
|
maven("https://www.cursemaven.com")
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -16,6 +17,8 @@ dependencies {
|
|||||||
|
|
||||||
"implementation"("kottle:Kottle:${properties["kottleVersion"]}")
|
"implementation"("kottle:Kottle:${properties["kottleVersion"]}")
|
||||||
"implementation"("org.spongepowered:mixin:0.8-SNAPSHOT")
|
"implementation"("org.spongepowered:mixin:0.8-SNAPSHOT")
|
||||||
|
|
||||||
|
"api"(fg.deobf("curse.maven:clothconfig-348521:2813656"))
|
||||||
}
|
}
|
||||||
|
|
||||||
configurations["annotationProcessor"].extendsFrom(configurations["implementation"])
|
configurations["annotationProcessor"].extendsFrom(configurations["implementation"])
|
||||||
@@ -45,6 +48,7 @@ java {
|
|||||||
kotlin {
|
kotlin {
|
||||||
target.compilations.configureEach {
|
target.compilations.configureEach {
|
||||||
kotlinOptions.freeCompilerArgs += listOf("-Xno-param-assertions", "-Xno-call-assertions")
|
kotlinOptions.freeCompilerArgs += listOf("-Xno-param-assertions", "-Xno-call-assertions")
|
||||||
|
kotlinOptions.jvmTarget = "1.8"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,33 +1,47 @@
|
|||||||
package mods.betterfoliage
|
package mods.betterfoliage
|
||||||
|
|
||||||
|
import me.shedaniel.forge.clothconfig2.api.ConfigBuilder
|
||||||
import mods.betterfoliage.client.Client
|
import mods.betterfoliage.client.Client
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.client.config.BlockConfig
|
||||||
import mods.betterfoliage.client.config.Config
|
import mods.betterfoliage.client.config.MainConfig
|
||||||
import mods.octarinecore.client.resource.AsnycSpriteProviderManager
|
import mods.octarinecore.common.config.clothGuiRoot
|
||||||
import mods.octarinecore.client.resource.GeneratedBlockTexturePack
|
import mods.octarinecore.common.config.forgeSpecRoot
|
||||||
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
import net.alexwells.kottle.FMLKotlinModLoadingContext
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.particle.ParticleManager
|
import net.minecraft.client.gui.screen.Screen
|
||||||
import net.minecraft.client.renderer.model.ModelBakery
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import net.minecraftforge.fml.ExtensionPoint.CONFIGGUIFACTORY
|
||||||
import net.minecraftforge.fml.ModLoadingContext
|
import net.minecraftforge.fml.ModLoadingContext
|
||||||
import net.minecraftforge.fml.common.Mod
|
import net.minecraftforge.fml.common.Mod
|
||||||
import net.minecraftforge.fml.config.ModConfig
|
import net.minecraftforge.fml.config.ModConfig
|
||||||
import org.apache.logging.log4j.Level.DEBUG
|
import org.apache.commons.lang3.tuple.Pair
|
||||||
import org.apache.logging.log4j.LogManager
|
import java.util.function.BiFunction
|
||||||
import org.apache.logging.log4j.simple.SimpleLogger
|
import java.util.function.BiPredicate
|
||||||
import org.apache.logging.log4j.util.PropertiesUtil
|
import java.util.function.Supplier
|
||||||
import java.io.File
|
|
||||||
import java.io.PrintStream
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
@Mod(BetterFoliageMod.MOD_ID)
|
@Mod(BetterFoliageMod.MOD_ID)
|
||||||
object BetterFoliageMod {
|
object BetterFoliageMod {
|
||||||
const val MOD_ID = "betterfoliage"
|
const val MOD_ID = "betterfoliage"
|
||||||
|
|
||||||
val bus = FMLKotlinModLoadingContext.get().modEventBus
|
val bus = FMLKotlinModLoadingContext.get().modEventBus
|
||||||
|
val config = MainConfig()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, Config.build())
|
val ctx = ModLoadingContext.get()
|
||||||
|
|
||||||
|
// Config instance + GUI handler
|
||||||
|
val configSpec = config.forgeSpecRoot()
|
||||||
|
ctx.registerConfig(ModConfig.Type.CLIENT, configSpec)
|
||||||
|
ctx.registerExtensionPoint(CONFIGGUIFACTORY) { BiFunction<Minecraft, Screen, Screen> { client, parent ->
|
||||||
|
config.clothGuiRoot(
|
||||||
|
parentScreen = parent,
|
||||||
|
prefix = listOf(MOD_ID),
|
||||||
|
background = ResourceLocation("minecraft:textures/block/spruce_wood.png"),
|
||||||
|
saveAction = { configSpec.save() }
|
||||||
|
)
|
||||||
|
} }
|
||||||
|
|
||||||
|
|
||||||
Minecraft.getInstance().resourcePackList.addPackFinder(BetterFoliage.asyncPack.finder)
|
Minecraft.getInstance().resourcePackList.addPackFinder(BetterFoliage.asyncPack.finder)
|
||||||
bus.register(BlockConfig)
|
bus.register(BlockConfig)
|
||||||
Client.init()
|
Client.init()
|
||||||
|
|||||||
@@ -1,23 +1,31 @@
|
|||||||
package mods.betterfoliage.client
|
package mods.betterfoliage.client
|
||||||
|
|
||||||
import mods.betterfoliage.BetterFoliageMod
|
|
||||||
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
import mods.betterfoliage.client.chunk.ChunkOverlayManager
|
||||||
import mods.betterfoliage.client.config.BlockConfig
|
import mods.betterfoliage.client.config.BlockConfig
|
||||||
import mods.betterfoliage.client.integration.*
|
import mods.betterfoliage.client.integration.OptifineCustomColors
|
||||||
import mods.betterfoliage.client.render.*
|
import mods.betterfoliage.client.integration.ShadersModIntegration
|
||||||
|
import mods.betterfoliage.client.render.AsyncCactusDiscovery
|
||||||
|
import mods.betterfoliage.client.render.AsyncLogDiscovery
|
||||||
|
import mods.betterfoliage.client.render.LeafWindTracker
|
||||||
|
import mods.betterfoliage.client.render.RenderAlgae
|
||||||
|
import mods.betterfoliage.client.render.RenderCactus
|
||||||
|
import mods.betterfoliage.client.render.RenderConnectedGrass
|
||||||
|
import mods.betterfoliage.client.render.RenderConnectedGrassLog
|
||||||
|
import mods.betterfoliage.client.render.RenderCoral
|
||||||
|
import mods.betterfoliage.client.render.RenderGrass
|
||||||
|
import mods.betterfoliage.client.render.RenderLeaves
|
||||||
|
import mods.betterfoliage.client.render.RenderLilypad
|
||||||
|
import mods.betterfoliage.client.render.RenderLog
|
||||||
|
import mods.betterfoliage.client.render.RenderMycelium
|
||||||
|
import mods.betterfoliage.client.render.RenderNetherrack
|
||||||
|
import mods.betterfoliage.client.render.RenderReeds
|
||||||
|
import mods.betterfoliage.client.render.RisingSoulTextures
|
||||||
import mods.betterfoliage.client.texture.AsyncGrassDiscovery
|
import mods.betterfoliage.client.texture.AsyncGrassDiscovery
|
||||||
import mods.betterfoliage.client.texture.AsyncLeafDiscovery
|
import mods.betterfoliage.client.texture.AsyncLeafDiscovery
|
||||||
import mods.betterfoliage.client.texture.LeafParticleRegistry
|
import mods.betterfoliage.client.texture.LeafParticleRegistry
|
||||||
import mods.octarinecore.client.gui.textComponent
|
|
||||||
import mods.octarinecore.client.render.RenderDecorator
|
import mods.octarinecore.client.render.RenderDecorator
|
||||||
import mods.octarinecore.client.resource.IConfigChangeListener
|
import mods.octarinecore.client.resource.IConfigChangeListener
|
||||||
import net.minecraft.block.BlockState
|
import net.minecraft.block.BlockState
|
||||||
import net.minecraft.client.Minecraft
|
|
||||||
import net.minecraft.util.math.BlockPos
|
|
||||||
import net.minecraft.util.text.TextFormatting
|
|
||||||
import net.minecraft.util.text.TranslationTextComponent
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries
|
|
||||||
import org.apache.logging.log4j.Level
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
|
* Object responsible for initializing (and holding a reference to) all the infrastructure of the mod
|
||||||
|
|||||||
@@ -8,139 +8,6 @@ import net.minecraft.util.ResourceLocation
|
|||||||
import net.minecraftforge.eventbus.api.SubscribeEvent
|
import net.minecraftforge.eventbus.api.SubscribeEvent
|
||||||
import net.minecraftforge.fml.config.ModConfig
|
import net.minecraftforge.fml.config.ModConfig
|
||||||
|
|
||||||
private fun featureEnable() = boolean(true).lang("enabled")
|
|
||||||
|
|
||||||
// Config singleton
|
|
||||||
object Config : DelegatingConfig(BetterFoliageMod.MOD_ID, BetterFoliageMod.MOD_ID) {
|
|
||||||
|
|
||||||
val enabled by boolean(true)
|
|
||||||
val nVidia by boolean(false)
|
|
||||||
|
|
||||||
object leaves : ConfigCategory() {
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val snowEnabled by boolean(true)
|
|
||||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
|
||||||
val vOffset by double(max=0.4, default=0.1).lang("vOffset")
|
|
||||||
val size by double(min=0.75, max=2.5, default=1.4).lang("size")
|
|
||||||
val dense by boolean(false)
|
|
||||||
val hideInternal by boolean(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
object shortGrass : ConfigCategory(){
|
|
||||||
val grassEnabled by boolean(true)
|
|
||||||
val myceliumEnabled by boolean(true)
|
|
||||||
val snowEnabled by boolean(true)
|
|
||||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
|
||||||
val heightMin by double(min=0.1, max=2.5, default=0.6).lang("heightMin")
|
|
||||||
val heightMax by double(min=0.1, max=2.5, default=0.8).lang("heightMax")
|
|
||||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
|
||||||
val population by int(max=64, default=64).lang("population")
|
|
||||||
val useGenerated by boolean(false)
|
|
||||||
val shaderWind by boolean(true).lang("shaderWind")
|
|
||||||
val saturationThreshold by double(default=0.1)
|
|
||||||
}
|
|
||||||
|
|
||||||
object connectedGrass : ConfigCategory(){
|
|
||||||
val enabled by boolean(true)
|
|
||||||
val snowEnabled by boolean(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
object roundLogs : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val radiusSmall by double(max=0.5, default=0.25)
|
|
||||||
val radiusLarge by double(max=0.5, default=0.44)
|
|
||||||
val dimming by double(default = 0.7)
|
|
||||||
val connectSolids by boolean(false)
|
|
||||||
val lenientConnect by boolean(true)
|
|
||||||
val connectPerpendicular by boolean(true)
|
|
||||||
val connectGrass by boolean(true)
|
|
||||||
val defaultY by boolean(false)
|
|
||||||
val zProtection by double(min = 0.9, default = 0.99)
|
|
||||||
}
|
|
||||||
|
|
||||||
object cactus : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val size by double(min=0.5, max=1.5, default=0.8).lang("size")
|
|
||||||
val sizeVariation by double(max=0.5, default=0.1)
|
|
||||||
val hOffset by double(max=0.5, default=0.1).lang("hOffset")
|
|
||||||
}
|
|
||||||
|
|
||||||
object lilypad : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val hOffset by double(max=0.25, default=0.1).lang("hOffset")
|
|
||||||
val flowerChance by int(max=64, default=16, min=0)
|
|
||||||
}
|
|
||||||
|
|
||||||
object reed : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
|
||||||
val heightMin by double(min=1.5, max=3.5, default=1.7).lang("heightMin")
|
|
||||||
val heightMax by double(min=1.5, max=3.5, default=2.2).lang("heightMax")
|
|
||||||
val population by int(max=64, default=32).lang("population")
|
|
||||||
val minBiomeTemp by double(default=0.4)
|
|
||||||
val minBiomeRainfall by double(default=0.4)
|
|
||||||
// val biomes by biomeList { it.filterTemp(0.4f, null) && it.filterRain(0.4f, null) }
|
|
||||||
val shaderWind by boolean(true).lang("shaderWind")
|
|
||||||
}
|
|
||||||
|
|
||||||
object algae : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val hOffset by double(max=0.25, default=0.1).lang("hOffset")
|
|
||||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
|
||||||
val heightMin by double(min=0.1, max=1.5, default=0.5).lang("heightMin")
|
|
||||||
val heightMax by double(min=0.1, max=1.5, default=1.0).lang("heightMax")
|
|
||||||
val population by int(max=64, default=48).lang("population")
|
|
||||||
// val biomes by biomeList { it.filterClass("river", "ocean") }
|
|
||||||
val shaderWind by boolean(true).lang("shaderWind")
|
|
||||||
}
|
|
||||||
|
|
||||||
object coral : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val shallowWater by boolean(false)
|
|
||||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
|
||||||
val vOffset by double(max=0.4, default=0.1).lang("vOffset")
|
|
||||||
val size by double(min=0.5, max=1.5, default=0.7).lang("size")
|
|
||||||
val crustSize by double(min=0.5, max=1.5, default=1.4)
|
|
||||||
val chance by int(max=64, default=32)
|
|
||||||
val population by int(max=64, default=48).lang("population")
|
|
||||||
// val biomes by biomeList { it.filterClass("river", "ocean", "beach") }
|
|
||||||
}
|
|
||||||
|
|
||||||
object netherrack : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val hOffset by double(max=0.4, default=0.2).lang("hOffset")
|
|
||||||
val heightMin by double(min=0.1, max=1.5, default=0.6).lang("heightMin")
|
|
||||||
val heightMax by double(min=0.1, max=1.5, default=0.8).lang("heightMax")
|
|
||||||
val size by double(min=0.5, max=1.5, default=1.0).lang("size")
|
|
||||||
}
|
|
||||||
|
|
||||||
object fallingLeaves : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val speed by double(min=0.01, max=0.15, default=0.05)
|
|
||||||
val windStrength by double(min=0.1, max=2.0, default=0.5)
|
|
||||||
val stormStrength by double(min=0.1, max=2.0, default=0.8)
|
|
||||||
val size by double(min=0.25, max=1.5, default=0.75).lang("size")
|
|
||||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
|
||||||
val perturb by double(min=0.01, max=1.0, default=0.25)
|
|
||||||
val lifetime by double(min=1.0, max=15.0, default=5.0)
|
|
||||||
val opacityHack by boolean(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
object risingSoul : ConfigCategory(){
|
|
||||||
val enabled by featureEnable()
|
|
||||||
val chance by double(min=0.001, max=1.0, default=0.02)
|
|
||||||
val perturb by double(min=0.01, max=0.25, default=0.05)
|
|
||||||
val headSize by double(min=0.25, max=1.5, default=1.0)
|
|
||||||
val trailSize by double(min=0.25, max=1.5, default=0.75)
|
|
||||||
val opacity by double(min=0.05, max=1.0, default=0.5)
|
|
||||||
val sizeDecay by double(min=0.5, max=1.0, default=0.97)
|
|
||||||
val opacityDecay by double(min=0.5, max=1.0, default=0.97)
|
|
||||||
val lifetime by double(min=1.0, max=15.0, default=4.0)
|
|
||||||
val trailLength by int(min=2, max=128, default=48)
|
|
||||||
val trailDensity by int(min=1, max=16, default=3)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object BlockConfig {
|
object BlockConfig {
|
||||||
private val list = mutableListOf<Any>()
|
private val list = mutableListOf<Any>()
|
||||||
|
|
||||||
|
|||||||
152
src/main/kotlin/mods/betterfoliage/client/config/MainConfig.kt
Normal file
152
src/main/kotlin/mods/betterfoliage/client/config/MainConfig.kt
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
package mods.betterfoliage.client.config
|
||||||
|
|
||||||
|
import mods.betterfoliage.BetterFoliageMod
|
||||||
|
import mods.octarinecore.common.config.DelegatingConfigGroup
|
||||||
|
import mods.octarinecore.common.config.boolean
|
||||||
|
import mods.octarinecore.common.config.double
|
||||||
|
import mods.octarinecore.common.config.integer
|
||||||
|
import mods.octarinecore.common.config.recurring
|
||||||
|
import mods.octarinecore.common.config.subNode
|
||||||
|
|
||||||
|
fun featureEnable(default: Boolean = true) = boolean(default, langKey = recurring)
|
||||||
|
|
||||||
|
val Config get() = BetterFoliageMod.config
|
||||||
|
|
||||||
|
class MainConfig : DelegatingConfigGroup() {
|
||||||
|
val enabled by boolean(true, langKey = { "betterfoliage.global.enabled" })
|
||||||
|
val nVidia by boolean(false)
|
||||||
|
|
||||||
|
val leaves by subNode(::LeavesConfig)
|
||||||
|
val shortGrass by subNode(::ShortGrassConfig)
|
||||||
|
val connectedGrass by subNode(::ConnectedGrassConfig)
|
||||||
|
val roundLogs by subNode(::RoundLogConfig)
|
||||||
|
val cactus by subNode(::CactusConfig)
|
||||||
|
val lilypad by subNode(::LilypadConfig)
|
||||||
|
val reed by subNode(::ReedConfig)
|
||||||
|
val algae by subNode(::AlgaeConfig)
|
||||||
|
val coral by subNode(::CoralConfig)
|
||||||
|
val netherrack by subNode(::NetherrackConfig)
|
||||||
|
val fallingLeaves by subNode(::FallingLeavesConfig)
|
||||||
|
val risingSoul by subNode(::RisingSoulConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
class LeavesConfig : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val snowEnabled by boolean(true)
|
||||||
|
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||||
|
val vOffset by double(max=0.4, default=0.1, langKey = recurring)
|
||||||
|
val size by double(min=0.75, max=2.5, default=1.4, langKey = recurring)
|
||||||
|
val dense by boolean(false)
|
||||||
|
val hideInternal by boolean(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ShortGrassConfig : DelegatingConfigGroup() {
|
||||||
|
val grassEnabled by boolean(true)
|
||||||
|
val myceliumEnabled by boolean(true)
|
||||||
|
val snowEnabled by boolean(true)
|
||||||
|
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||||
|
val heightMin by double(min=0.1, max=2.5, default=0.6, langKey = recurring)
|
||||||
|
val heightMax by double(min=0.1, max=2.5, default=0.8, langKey = recurring)
|
||||||
|
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||||
|
val population by integer(max=64, default=64)
|
||||||
|
val useGenerated by boolean(false)
|
||||||
|
val shaderWind by boolean(true, langKey = recurring)
|
||||||
|
val saturationThreshold by double(default=0.1)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConnectedGrassConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by boolean(true)
|
||||||
|
val snowEnabled by boolean(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
class RoundLogConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val radiusSmall by double(max=0.5, default=0.25)
|
||||||
|
val radiusLarge by double(max=0.5, default=0.44)
|
||||||
|
val dimming by double(default = 0.7)
|
||||||
|
val connectSolids by boolean(false)
|
||||||
|
val lenientConnect by boolean(true)
|
||||||
|
val connectPerpendicular by boolean(true)
|
||||||
|
val connectGrass by boolean(true)
|
||||||
|
val defaultY by boolean(false)
|
||||||
|
val zProtection by double(min = 0.9, default = 0.99)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CactusConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val size by double(min=0.5, max=1.5, default=0.8, langKey = recurring)
|
||||||
|
val sizeVariation by double(max=0.5, default=0.1)
|
||||||
|
val hOffset by double(max=0.5, default=0.1, langKey = recurring)
|
||||||
|
}
|
||||||
|
|
||||||
|
class LilypadConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val hOffset by double(max=0.25, default=0.1, langKey = recurring)
|
||||||
|
val flowerChance by integer(max=64, default=16, min=0)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReedConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||||
|
val heightMin by double(min=1.5, max=3.5, default=1.7, langKey = recurring)
|
||||||
|
val heightMax by double(min=1.5, max=3.5, default=2.2, langKey = recurring)
|
||||||
|
val population by integer(max=64, default=32, langKey = recurring)
|
||||||
|
val minBiomeTemp by double(default=0.4)
|
||||||
|
val minBiomeRainfall by double(default=0.4)
|
||||||
|
val shaderWind by boolean(true, langKey = recurring)
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlgaeConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val hOffset by double(max=0.25, default=0.1, langKey = recurring)
|
||||||
|
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||||
|
val heightMin by double(min=0.1, max=1.5, default=0.5, langKey = recurring)
|
||||||
|
val heightMax by double(min=0.1, max=1.5, default=1.0, langKey = recurring)
|
||||||
|
val population by integer(max=64, default=48, langKey = recurring)
|
||||||
|
val shaderWind by boolean(true, langKey = recurring)
|
||||||
|
}
|
||||||
|
|
||||||
|
class CoralConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val shallowWater by boolean(false)
|
||||||
|
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||||
|
val vOffset by double(max=0.4, default=0.1, langKey = recurring)
|
||||||
|
val size by double(min=0.5, max=1.5, default=0.7, langKey = recurring)
|
||||||
|
val crustSize by double(min=0.5, max=1.5, default=1.4)
|
||||||
|
val chance by integer(max=64, default=32)
|
||||||
|
val population by integer(max=64, default=48, langKey = recurring)
|
||||||
|
}
|
||||||
|
|
||||||
|
class NetherrackConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val hOffset by double(max=0.4, default=0.2, langKey = recurring)
|
||||||
|
val heightMin by double(min=0.1, max=1.5, default=0.6, langKey = recurring)
|
||||||
|
val heightMax by double(min=0.1, max=1.5, default=0.8, langKey = recurring)
|
||||||
|
val size by double(min=0.5, max=1.5, default=1.0, langKey = recurring)
|
||||||
|
}
|
||||||
|
|
||||||
|
class FallingLeavesConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val speed by double(min=0.01, max=0.15, default=0.05)
|
||||||
|
val windStrength by double(min=0.1, max=2.0, default=0.5)
|
||||||
|
val stormStrength by double(min=0.1, max=2.0, default=0.8)
|
||||||
|
val size by double(min=0.25, max=1.5, default=0.75, langKey = recurring)
|
||||||
|
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||||
|
val perturb by double(min=0.01, max=1.0, default=0.25)
|
||||||
|
val lifetime by double(min=1.0, max=15.0, default=5.0)
|
||||||
|
val opacityHack by boolean(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
class RisingSoulConfig() : DelegatingConfigGroup() {
|
||||||
|
val enabled by featureEnable()
|
||||||
|
val chance by double(min=0.001, max=1.0, default=0.02)
|
||||||
|
val perturb by double(min=0.01, max=0.25, default=0.05)
|
||||||
|
val headSize by double(min=0.25, max=1.5, default=1.0)
|
||||||
|
val trailSize by double(min=0.25, max=1.5, default=0.75)
|
||||||
|
val opacity by double(min=0.05, max=1.0, default=0.5)
|
||||||
|
val sizeDecay by double(min=0.5, max=1.0, default=0.97)
|
||||||
|
val opacityDecay by double(min=0.5, max=1.0, default=0.97)
|
||||||
|
val lifetime by double(min=1.0, max=15.0, default=4.0)
|
||||||
|
val trailLength by integer(min=2, max=128, default=48)
|
||||||
|
val trailDensity by integer(min=1, max=16, default=3)
|
||||||
|
}
|
||||||
172
src/main/kotlin/mods/octarinecore/common/config/Delegate.kt
Normal file
172
src/main/kotlin/mods/octarinecore/common/config/Delegate.kt
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
package mods.octarinecore.common.config
|
||||||
|
|
||||||
|
import me.shedaniel.forge.clothconfig2.api.AbstractConfigListEntry
|
||||||
|
import me.shedaniel.forge.clothconfig2.api.ConfigBuilder
|
||||||
|
import me.shedaniel.forge.clothconfig2.api.ConfigEntryBuilder
|
||||||
|
import me.shedaniel.forge.clothconfig2.gui.entries.SubCategoryListEntry
|
||||||
|
import net.minecraft.client.gui.screen.Screen
|
||||||
|
import net.minecraft.client.resources.I18n
|
||||||
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import net.minecraftforge.common.ForgeConfigSpec
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
const val MAX_LINE_LEN = 30
|
||||||
|
|
||||||
|
fun DelegatingConfigGroup.forgeSpecRoot() =
|
||||||
|
ForgeConfigSpec.Builder()
|
||||||
|
.also { createForgeNode(it) }
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun DelegatingConfigGroup.clothGuiRoot(
|
||||||
|
parentScreen: Screen,
|
||||||
|
prefix: List<String>,
|
||||||
|
background: ResourceLocation,
|
||||||
|
saveAction: ()->Unit
|
||||||
|
) = ConfigBuilder.create()
|
||||||
|
.setParentScreen(parentScreen)
|
||||||
|
.setTitle(I18n.format((prefix + "title").joinToString(".")))
|
||||||
|
.setDefaultBackgroundTexture(background)
|
||||||
|
.setSavingRunnable(saveAction)
|
||||||
|
.also { builder ->
|
||||||
|
createClothNode(prefix).value.forEach { rootCategory ->
|
||||||
|
builder.getOrCreateCategory("main").addEntry(rootCategory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
|
||||||
|
sealed class DelegatingConfigNode {
|
||||||
|
abstract fun createClothNode(path: List<String>): AbstractConfigListEntry<*>
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DelegatingConfigValue<T> : DelegatingConfigNode(), ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||||
|
lateinit var forgeValue: ForgeConfigSpec.ConfigValue<T>
|
||||||
|
abstract fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class DelegatingConfigGroup : DelegatingConfigNode() {
|
||||||
|
val children = mutableMapOf<String, DelegatingConfigNode>()
|
||||||
|
|
||||||
|
fun createForgeNode(builder: ForgeConfigSpec.Builder) {
|
||||||
|
children.forEach { (name, node) ->
|
||||||
|
when(node) {
|
||||||
|
is DelegatingConfigGroup -> {
|
||||||
|
builder.push(name)
|
||||||
|
node.createForgeNode(builder)
|
||||||
|
builder.pop()
|
||||||
|
}
|
||||||
|
is DelegatingConfigValue<*> -> node.createForgeNode(builder, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createClothNode(path: List<String>): SubCategoryListEntry {
|
||||||
|
val builder = ConfigEntryBuilder.create()
|
||||||
|
.startSubCategory(path.joinToString(".").translate())
|
||||||
|
.setTooltip(*path.joinToString(".").translateTooltip())
|
||||||
|
.setExpended(false)
|
||||||
|
children.forEach { (name, node) -> builder.add(node.createClothNode(path + name)) }
|
||||||
|
return builder.build()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DelegatingConfigGroupFactory<T> {
|
||||||
|
operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T: DelegatingConfigGroup> subNode(factory: ()->T) = object : DelegatingConfigGroupFactory<T> {
|
||||||
|
override operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||||
|
val child = factory()
|
||||||
|
parent.children[property.name] = child
|
||||||
|
return object : ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||||
|
override fun getValue(thisRef: DelegatingConfigGroup, property: KProperty<*>) = child
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface DelegatingConfigValueFactory<T> {
|
||||||
|
fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String): ForgeConfigSpec.ConfigValue<T>
|
||||||
|
fun createClothNode(prop: CachingConfigProperty<T>, path: List<String>): AbstractConfigListEntry<T>
|
||||||
|
|
||||||
|
operator fun provideDelegate(parent: DelegatingConfigGroup, property: KProperty<*>): ReadOnlyProperty<DelegatingConfigGroup, T> {
|
||||||
|
return object : CachingConfigProperty<T>(parent, property) {
|
||||||
|
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) {
|
||||||
|
forgeValue = this@DelegatingConfigValueFactory.createForgeNode(builder, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createClothNode(path: List<String>): AbstractConfigListEntry<*> = createClothNode(this, path)
|
||||||
|
|
||||||
|
}.apply { parent.children[property.name] = this }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class CachingConfigProperty<T>(parent: DelegatingConfigGroup, property: KProperty<*>) : DelegatingConfigValue<T>() {
|
||||||
|
var value: T? = null
|
||||||
|
override fun getValue(thisRef: DelegatingConfigGroup, property: KProperty<*>) =
|
||||||
|
value ?: forgeValue.get().apply { value = this }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun String.translate() = I18n.format(this)
|
||||||
|
fun String.translateTooltip(lineLength: Int = MAX_LINE_LEN) = ("$this.tooltip").translate().let { tooltip ->
|
||||||
|
tooltip.splitToSequence(" ").fold(mutableListOf("")) { tooltips, word ->
|
||||||
|
if (tooltips.last().length + word.length < lineLength) {
|
||||||
|
tooltips[tooltips.lastIndex] += "$word "
|
||||||
|
} else {
|
||||||
|
tooltips.add("$word ")
|
||||||
|
}
|
||||||
|
tooltips
|
||||||
|
}.map { it.trim() }.toTypedArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun boolean(
|
||||||
|
default: Boolean,
|
||||||
|
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||||
|
valueOverride: (Boolean)->Boolean = { it }
|
||||||
|
) = object : DelegatingConfigValueFactory<Boolean> {
|
||||||
|
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||||
|
builder.define(name, default)
|
||||||
|
|
||||||
|
override fun createClothNode(prop: CachingConfigProperty<Boolean>, path: List<String>) = ConfigEntryBuilder.create()
|
||||||
|
.startBooleanToggle(langKey(path).translate(), prop.forgeValue.get())
|
||||||
|
.setTooltip(langKey(path).let { if (I18n.hasKey("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||||
|
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun integer(
|
||||||
|
default: Int = 0, min: Int = 0, max: Int,
|
||||||
|
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||||
|
valueOverride: (Int)->Int = { it }
|
||||||
|
) = object : DelegatingConfigValueFactory<Int> {
|
||||||
|
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||||
|
builder.defineInRange(name, default, min, max)
|
||||||
|
|
||||||
|
override fun createClothNode(prop: CachingConfigProperty<Int>, path: List<String>) = ConfigEntryBuilder.create()
|
||||||
|
.startIntField(langKey(path).translate(), prop.forgeValue.get())
|
||||||
|
.setTooltip(langKey(path).let { if (I18n.hasKey("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||||
|
.setMin(min).setMax(max)
|
||||||
|
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun double(
|
||||||
|
default: Double = 0.0, min: Double = 0.0, max: Double = 1.0,
|
||||||
|
langKey: (List<String>)->String = { it.joinToString(".") },
|
||||||
|
valueOverride: (Double)->Double = { it }
|
||||||
|
) = object : DelegatingConfigValueFactory<Double> {
|
||||||
|
override fun createForgeNode(builder: ForgeConfigSpec.Builder, name: String) =
|
||||||
|
builder.defineInRange(name, default, min, max)
|
||||||
|
|
||||||
|
override fun createClothNode(prop: CachingConfigProperty<Double>, path: List<String>) = ConfigEntryBuilder.create()
|
||||||
|
.startDoubleField(langKey(path).translate(), prop.forgeValue.get())
|
||||||
|
.setTooltip(langKey(path).let { if (I18n.hasKey("$it.tooltip")) Optional.of(it.translateTooltip()) else Optional.empty() })
|
||||||
|
.setMin(min).setMax(max)
|
||||||
|
.setSaveConsumer { prop.forgeValue.set(valueOverride(it)); prop.value = null }
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
val recurring = { path: List<String> -> "${path.first()}.${path.last()}" }
|
||||||
|
fun fakeCategory(name: String) = { names: List<String> ->
|
||||||
|
(listOf(names.first(), name) + names.drop(1)).joinToString(".")
|
||||||
|
}
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
@file:JvmName("DelegatingConfigKt")
|
|
||||||
|
|
||||||
package mods.octarinecore.common.config
|
|
||||||
|
|
||||||
import mods.octarinecore.metaprog.reflectDelegates
|
|
||||||
import mods.octarinecore.metaprog.reflectNestedObjects
|
|
||||||
import net.minecraftforge.common.ForgeConfigSpec
|
|
||||||
import kotlin.properties.ReadOnlyProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
open class DelegatingConfig(val modId: String, val langPrefix: String) {
|
|
||||||
fun build() = ForgeConfigSpec.Builder().apply { ConfigBuildContext(langPrefix, emptyList(), this).addCategory(this@DelegatingConfig) }.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
class ConfigBuildContext(val langPrefix: String, val path: List<String>, val builder: ForgeConfigSpec.Builder) {
|
|
||||||
|
|
||||||
fun addCategory(configObj: Any) {
|
|
||||||
configObj.reflectNestedObjects.forEach { (name, category) ->
|
|
||||||
builder.push(name)
|
|
||||||
descend(name).addCategory(category)
|
|
||||||
builder.pop()
|
|
||||||
}
|
|
||||||
configObj.reflectDelegates(ConfigDelegate::class.java).forEach { (name, delegate) ->
|
|
||||||
descend(name).apply { delegate.addToBuilder(this) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun descend(pathName: String) = ConfigBuildContext(langPrefix, path + pathName, builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
open class ConfigCategory(val comment: String? = null) {
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class ConfigDelegate<T> : ReadOnlyProperty<Any, T> {
|
|
||||||
lateinit var configValue: ForgeConfigSpec.ConfigValue<T>
|
|
||||||
var cachedValue: T? = null
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any, property: KProperty<*>): T {
|
|
||||||
if (cachedValue == null) cachedValue = configValue.get()
|
|
||||||
return cachedValue!!
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder): ForgeConfigSpec.ConfigValue<T>
|
|
||||||
fun addToBuilder(ctx: ConfigBuildContext) {
|
|
||||||
val langKey = ctx.langPrefix + "." + (langPrefixOverride ?: ctx.path.joinToString("."))
|
|
||||||
ctx.builder.translation(langKey)
|
|
||||||
configValue = getConfigValue(ctx.path.last(), ctx.builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
var langPrefixOverride: String? = null
|
|
||||||
fun lang(prefix: String) = apply { langPrefixOverride = prefix }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegatingBooleanValue(val defaultValue: Boolean) : ConfigDelegate<Boolean>() {
|
|
||||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.define(name, defaultValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegatingIntValue(
|
|
||||||
val minValue: Int = 0,
|
|
||||||
val maxValue: Int = 1,
|
|
||||||
val defaultValue: Int = 0
|
|
||||||
) : ConfigDelegate<Int>() {
|
|
||||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegatingLongValue(
|
|
||||||
val minValue: Long = 0,
|
|
||||||
val maxValue: Long = 1,
|
|
||||||
val defaultValue: Long = 0
|
|
||||||
) : ConfigDelegate<Long>() {
|
|
||||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
class DelegatingDoubleValue(
|
|
||||||
val minValue: Double = 0.0,
|
|
||||||
val maxValue: Double = 1.0,
|
|
||||||
val defaultValue: Double = 0.0
|
|
||||||
) : ConfigDelegate<Double>() {
|
|
||||||
override fun getConfigValue(name: String, builder: ForgeConfigSpec.Builder) = builder.defineInRange(name, defaultValue, minValue, maxValue)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================
|
|
||||||
// Delegate factory methods
|
|
||||||
// ============================
|
|
||||||
fun double(min: Double = 0.0, max: Double = 1.0, default: Double) = DelegatingDoubleValue(min, max, default)
|
|
||||||
fun int(min: Int = 0, max: Int, default: Int) = DelegatingIntValue(min, max, default)
|
|
||||||
fun long(min: Long = 0, max: Long, default: Long) = DelegatingLongValue(min, max, default)
|
|
||||||
fun boolean(default: Boolean) = DelegatingBooleanValue(default)
|
|
||||||
Reference in New Issue
Block a user