From c69fd5683831b25148cc0ba49f06f911d51e7560 Mon Sep 17 00:00:00 2001 From: Username404 Date: Sat, 29 May 2021 22:11:05 +0200 Subject: [PATCH] Add a cloth config screen --- build.gradle.kts | 3 +- common/build.gradle.kts | 1 + .../snowygui/config/ConfigScreen.kt | 40 +++++++++++++++++-- .../snowygui/config/Configuration.kt | 16 +++++--- .../snowygui/gui/feature/ButtonAnnotations.kt | 2 +- .../snowygui/gui/feature/ButtonImpl.kt | 2 +- .../snowygui/gui/feature/Colors.kt | 1 + .../snowygui/gui/feature/RiskyCheats.kt | 4 +- .../username404/snowygui/misc/AddKeyMaps.kt | 3 +- .../resources/assets/snowygui/lang/en_us.json | 2 + .../resources/assets/snowygui/lang/fr_fr.json | 2 + fabric/build.gradle.kts | 1 + .../snowygui/fabric/ModMenuConf.kt | 8 ++-- fabric/src/main/resources/fabric.mod.json | 3 ++ forge/build.gradle.kts | 1 + .../username404/snowygui/forge/ForgeInit.kt | 13 ++---- forge/src/main/resources/META-INF/mods.toml | 7 ++++ gradle.properties | 1 + 18 files changed, 81 insertions(+), 29 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index eea959d..4966cac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -200,7 +200,8 @@ allprojects { "java_version" to javaVer, "mod_group" to this@allprojects.group, "fabric_kotlin" to rootProject.property("fabric_language_kotlin"), - "kotlinforforge" to rootProject.property("kotlinforforge") + "kotlinforforge" to rootProject.property("kotlinforforge"), + "clothconfig" to rootProject.property("clothconfig_version") ) inputs.properties(modProperties) filesNotMatching(listOf("*.png")) { diff --git a/common/build.gradle.kts b/common/build.gradle.kts index d655510..4c9d136 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -1,5 +1,6 @@ architectury { common(); injectInjectables = false } dependencies { modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}") + implementation("me.shedaniel.cloth:cloth-config:${rootProject.property("clothconfig_version")}") } diff --git a/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt b/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt index 8d7d211..b8410d1 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/config/ConfigScreen.kt @@ -1,11 +1,45 @@ package fr.username404.snowygui.config import com.mojang.blaze3d.vertex.PoseStack +import fr.username404.snowygui.gui.FontUtil +import fr.username404.snowygui.gui.feature.Colors +import fr.username404.snowygui.gui.feature.riskyCheatsEnabled import net.minecraft.client.gui.screens.Screen +import net.minecraft.network.chat.Component import net.minecraft.network.chat.TranslatableComponent -open class SnowyConfigScreen: Screen(TranslatableComponent("screen.snowygui.config")) { // TODO Actual config screen - override fun render(poseStack: PoseStack?, i: Int, j: Int, f: Float) { - renderBackground(poseStack) +private const val confPrefix: String = "screen.snowy.config" +private val translationComponent = TranslatableComponent(confPrefix) + +var configScreenParent: Screen? = null + +val SnowyConfigScreen: Screen get() { + return try { + Class.forName("me.shedaniel.clothconfig2.api.ConfigBuilder") + me.shedaniel.clothconfig2.api.ConfigBuilder.create().setParentScreen(configScreenParent).transparentBackground() + .setShouldListSmoothScroll(true) + .setTitle(translationComponent).apply { + with(entryBuilder()) { + getOrCreateCategory(TranslatableComponent("$confPrefix.general")).addEntry( + startBooleanToggle(Component.nullToEmpty("Risky Cheats"), riskyCheatsEnabled) + .requireRestart() + .setSaveConsumer { + riskyCheatsEnabled = it + }.build() + ).addEntry(startSubCategory(TranslatableComponent("$confPrefix.behavior")).build()) + } + }.build() + } catch (e: ClassNotFoundException) { + object : Screen(translationComponent) { + override fun isPauseScreen(): Boolean = false + override fun render(poseStack: PoseStack?, i: Int, j: Int, f: Float) { + super.renderBackground(poseStack) + FontUtil.drawScaled(poseStack!!, + text = "Cloth Config is required for the configuration of snowygui, please install it.", 50.0, 50.0, + color = Colors.WHITE, scaleFactor = 1.85F + ) + } + override fun onClose() { minecraft?.screen = configScreenParent } + } } } \ No newline at end of file diff --git a/common/src/main/kotlin/fr/username404/snowygui/config/Configuration.kt b/common/src/main/kotlin/fr/username404/snowygui/config/Configuration.kt index 0ce54a0..8e8b788 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/config/Configuration.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/config/Configuration.kt @@ -1,14 +1,12 @@ package fr.username404.snowygui.config -import com.typesafe.config.Config -import com.typesafe.config.ConfigException +import com.typesafe.config.* import com.typesafe.config.ConfigFactory.* -import com.typesafe.config.ConfigRenderOptions -import com.typesafe.config.ConfigValueFactory import fr.username404.snowygui.ClickGui import fr.username404.snowygui.Snowy import fr.username404.snowygui.gui.feature.ButtonImpl import fr.username404.snowygui.gui.feature.Macro +import fr.username404.snowygui.gui.feature.riskyCheatsEnabled import io.github.config4k.extract import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch @@ -16,8 +14,16 @@ import kotlinx.coroutines.runBlocking import net.minecraft.client.Minecraft import java.io.File import java.nio.charset.Charset +import java.util.function.Supplier object Configuration { + val ModifiableValues = mutableMapOf>( + "enabledFeatures" to Supplier { ConfigValueFactory.fromMap(enabledFeatures) }, + "riskyCheats" to Supplier { ConfigValueFactory.fromAnyRef(riskyCheatsEnabled) } + ); inline fun setConfigValue(s: String, crossinline value: () -> Any) = ModifiableValues.put(s, Supplier { ConfigValueFactory.fromAnyRef(value.invoke()) }) + private fun Config.withFullModifiableValues() = ModifiableValues.entries.fold(this) { previous, entry -> + previous.withValue(entry.key, entry.value.get()) + } private val file: File = File(Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "snowy.conf") private val macroFile: File = File(Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "snowy-macros.json") private suspend fun writeConfig(c: Config) = coroutineScope { @@ -99,7 +105,7 @@ object Configuration { } } } - writeConfig(obtained.withValue("enabledFeatures", ConfigValueFactory.fromMap(enabledFeatures))).join() + writeConfig(obtained.withFullModifiableValues()).join() } } ) diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonAnnotations.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonAnnotations.kt index 899549a..1c0ee40 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonAnnotations.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonAnnotations.kt @@ -27,7 +27,7 @@ annotation class ButtonInfo( init { ClickGui.components.add( ClickBox( - x = 4.0 + (if (ordinal >= 1 && !riskyCheats) ordinal - 1 else ordinal) * 86, y = 4.0, + x = 4.0 + (if (ordinal >= 1 && !riskyCheatsEnabled) ordinal - 1 else ordinal) * 86, y = 4.0, name = TranslatableComponent(translationKey), color = categoryColor ) diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt index b6d1f45..f6ac169 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/ButtonImpl.kt @@ -51,7 +51,7 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) { } catch (e: NoSuchFieldException) {} }) as? ButtonImpl) }.filterNotNull().filterNot { - (it.info.parent == Category.RISKY) && !riskyCheats + (it.info.parent == Category.RISKY) && !riskyCheatsEnabled }.plus(Configuration.macros) ) } diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt index e6f8b8b..3a7365d 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/Colors.kt @@ -3,6 +3,7 @@ package fr.username404.snowygui.gui.feature enum class Colors(val hexValue: Int) { TRANSPARENT(-0x1), BLACK(0x000000), + WHITE(0xFFFFFF), GOLD(0xe69500), BLUE(0x6C9E9D), RED(0x660000), diff --git a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/RiskyCheats.kt b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/RiskyCheats.kt index 7b882e8..1ade49b 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/gui/feature/RiskyCheats.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/gui/feature/RiskyCheats.kt @@ -1,10 +1,10 @@ package fr.username404.snowygui.gui.feature import fr.username404.snowygui.config.Configuration +import io.github.config4k.extract import net.minecraft.client.Minecraft -import io.github.config4k.getValue -val riskyCheats: Boolean by Configuration.obtained +internal var riskyCheatsEnabled = Configuration.obtained.extract("riskyCheats") @ButtonInfo(Category.RISKY) object NoHurtCamera: ButtonImpl() diff --git a/common/src/main/kotlin/fr/username404/snowygui/misc/AddKeyMaps.kt b/common/src/main/kotlin/fr/username404/snowygui/misc/AddKeyMaps.kt index a215765..747bf65 100644 --- a/common/src/main/kotlin/fr/username404/snowygui/misc/AddKeyMaps.kt +++ b/common/src/main/kotlin/fr/username404/snowygui/misc/AddKeyMaps.kt @@ -3,6 +3,7 @@ package fr.username404.snowygui.misc import com.mojang.blaze3d.platform.InputConstants import fr.username404.snowygui.ClickGui import fr.username404.snowygui.config.SnowyConfigScreen +import fr.username404.snowygui.config.configScreenParent import net.minecraft.client.KeyMapping import net.minecraft.client.Minecraft import org.lwjgl.glfw.GLFW.GLFW_KEY_U @@ -20,6 +21,6 @@ object AddKeyMaps { } val list: MutableMap Unit)?> = mutableMapOf( mkMap("opengui", GLFW_KEY_Y) { Minecraft.getInstance().setScreen(ClickGui) }, - mkMap("configkey", GLFW_KEY_U) { Minecraft.getInstance().setScreen(SnowyConfigScreen()) } + mkMap("configkey", GLFW_KEY_U) { Minecraft.getInstance().setScreen(run { configScreenParent = null; SnowyConfigScreen }) } ) } \ No newline at end of file diff --git a/common/src/main/resources/assets/snowygui/lang/en_us.json b/common/src/main/resources/assets/snowygui/lang/en_us.json index 77d73bf..79275be 100644 --- a/common/src/main/resources/assets/snowygui/lang/en_us.json +++ b/common/src/main/resources/assets/snowygui/lang/en_us.json @@ -1,6 +1,8 @@ { "screen.snowy.gui": "Snowy Interface", "screen.snowy.config": "Snowy configuration screen", + "screen.snowy.config.general": "General", + "screen.snowy.config.behavior": "Behavior", "category.snowy.keycategory": "SnowyGUI", "key.snowy.opengui": "Open the snowy gui", "key.snowy.configkey": "Open the snowy configuration screen", diff --git a/common/src/main/resources/assets/snowygui/lang/fr_fr.json b/common/src/main/resources/assets/snowygui/lang/fr_fr.json index 15a2e40..c633d9e 100644 --- a/common/src/main/resources/assets/snowygui/lang/fr_fr.json +++ b/common/src/main/resources/assets/snowygui/lang/fr_fr.json @@ -1,6 +1,8 @@ { "screen.snowy.gui": "Interface de Snowy", "screen.snowy.config": "Configuration de snowy", + "screen.snowy.config.general": "Général", + "screen.snowy.config.behavior": "Comportement", "category.snowy.keycategory": "SnowyGUI", "key.snowy.opengui": "Ouvrir l'interface de snowy", "key.snowy.configkey": "Ouvrir l'écran de configuration de snowy", diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts index 58f7c89..c70db79 100644 --- a/fabric/build.gradle.kts +++ b/fabric/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { modImplementation("${Groups.Fabric}:fabric-loader:${rootProject.property("fabric_loader_version")}") include(modApi("${Groups.FabricApi}:fabric-rendering-v1:${rootProject.property("fabric_rendering_api_version")}")!!) include(modApi("${Groups.FabricApi}:fabric-api-base:${rootProject.property("fabric_api_base_version")}")!!) + modApi("me.shedaniel.cloth:cloth-config-fabric:${rootProject.property("clothconfig_version")}") { exclude(group = Groups.FabricApi) } include(modRuntime("${Groups.FabricApi}:fabric-resource-loader-v0:${rootProject.property("fabric_resource_loader_version")}")!!) modImplementation(group = "net.fabricmc", name = "fabric-language-kotlin", version = rootProject.property("fabric_language_kotlin") as String) listOf("net.oneandone.reflections8:reflections8:0.11.7", "org.javassist:javassist:3.28.0-GA").forEach { implementation(it); shadowC(it) { isTransitive = false } } diff --git a/fabric/src/main/kotlin/fr/username404/snowygui/fabric/ModMenuConf.kt b/fabric/src/main/kotlin/fr/username404/snowygui/fabric/ModMenuConf.kt index a50adb8..9153d8b 100644 --- a/fabric/src/main/kotlin/fr/username404/snowygui/fabric/ModMenuConf.kt +++ b/fabric/src/main/kotlin/fr/username404/snowygui/fabric/ModMenuConf.kt @@ -3,16 +3,14 @@ package fr.username404.snowygui.fabric import com.terraformersmc.modmenu.api.ConfigScreenFactory import com.terraformersmc.modmenu.api.ModMenuApi import fr.username404.snowygui.config.SnowyConfigScreen +import fr.username404.snowygui.config.configScreenParent import net.minecraft.client.gui.screens.Screen class ModMenuConf: ModMenuApi { override fun getModConfigScreenFactory(): ConfigScreenFactory { return ConfigScreenFactory { screen: Screen? -> - object : SnowyConfigScreen() { - override fun onClose() { - minecraft!!.setScreen(screen) - } - } + configScreenParent = screen!! + SnowyConfigScreen } } } \ No newline at end of file diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json index 6bce513..5711f54 100644 --- a/fabric/src/main/resources/fabric.mod.json +++ b/fabric/src/main/resources/fabric.mod.json @@ -37,6 +37,9 @@ "fabric-rendering-v1": "*", "minecraft": ">=${minecraft_version}" }, + "recommends": { + "cloth-config2": ">=${clothconfig}" + }, "breaks": { "java": "<${java_version}", "modmenu": "<1.15.0" diff --git a/forge/build.gradle.kts b/forge/build.gradle.kts index 1816737..b91622d 100644 --- a/forge/build.gradle.kts +++ b/forge/build.gradle.kts @@ -7,6 +7,7 @@ val serializationVer: String by rootProject dependencies { forge("net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.property("forge_version")}.+") implementation("thedarkcolour:kotlinforforge:${rootProject.property("kotlinforforge")}") + api("me.shedaniel.cloth:cloth-config-forge:${rootProject.property("clothconfig_version")}") implementation(project(path = ":common")) { isTransitive = false } add("developmentForge", project(path = ":common")) { isTransitive = false } shadowC("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVer") { isTransitive = false } // Needed for kotlinx-datetime diff --git a/forge/src/main/kotlin/fr/username404/snowygui/forge/ForgeInit.kt b/forge/src/main/kotlin/fr/username404/snowygui/forge/ForgeInit.kt index eca98ed..ac3e2ec 100644 --- a/forge/src/main/kotlin/fr/username404/snowygui/forge/ForgeInit.kt +++ b/forge/src/main/kotlin/fr/username404/snowygui/forge/ForgeInit.kt @@ -2,6 +2,7 @@ package fr.username404.snowygui.forge import fr.username404.snowygui.Snowy import fr.username404.snowygui.config.SnowyConfigScreen +import fr.username404.snowygui.config.configScreenParent import fr.username404.snowygui.gui.feature.ButtonImpl import fr.username404.snowygui.gui.feature.ButtonInfo import net.minecraftforge.fml.ExtensionPoint @@ -14,7 +15,6 @@ import thedarkcolour.kotlinforforge.forge.FORGE_BUS import thedarkcolour.kotlinforforge.forge.LOADING_CONTEXT import thedarkcolour.kotlinforforge.forge.MOD_BUS import java.util.function.BiFunction -import java.util.function.Supplier import java.util.stream.Collectors @Mod("snowygui") @@ -23,15 +23,8 @@ class ForgeInit: Snowy() { private fun initSetup(event: FMLClientSetupEvent) = atInit() private fun configSetup(event: FMLClientSetupEvent) { LOADING_CONTEXT.registerExtensionPoint( - ExtensionPoint.CONFIGGUIFACTORY, - Supplier { - return@Supplier BiFunction { mc, screen -> - return@BiFunction object : SnowyConfigScreen() { - override fun onClose() { mc.setScreen(screen) } - } - } - } - ) + ExtensionPoint.CONFIGGUIFACTORY + ) { BiFunction { _, parent -> configScreenParent = parent; SnowyConfigScreen } } } init { annotatedButtons = ModList.get() // Forge-specific reflection diff --git a/forge/src/main/resources/META-INF/mods.toml b/forge/src/main/resources/META-INF/mods.toml index 01137f8..572c844 100644 --- a/forge/src/main/resources/META-INF/mods.toml +++ b/forge/src/main/resources/META-INF/mods.toml @@ -13,6 +13,13 @@ A cross-platform mod offering a useful interface. ''' logoFile = "icon.png" +[[dependencies.snowygui]] +modId = "cloth-config" +mandatory = false +versionRange = "[${clothconfig},)" +ordering = "BEFORE" +side = "CLIENT" + [[dependencies.snowygui]] modId = "forge" mandatory = true diff --git a/gradle.properties b/gradle.properties index 9ff0e55..328a478 100644 --- a/gradle.properties +++ b/gradle.properties @@ -17,4 +17,5 @@ fabric_language_kotlin=1.6.0+kotlin.1.5.0 fabric_resource_loader_version=0.2.5+059ea8667c fabric_rendering_api_version=1.1.2+346247d77c fabric_api_base_version=0.1.3+12a8474c7c +clothconfig_version=4.11.19 modmenu_version=1.16.9 \ No newline at end of file