diff --git a/assets/enchant-menu.aseprite b/assets/enchant-menu.aseprite index a6b076c..5e26e27 100644 Binary files a/assets/enchant-menu.aseprite and b/assets/enchant-menu.aseprite differ diff --git a/build.gradle.kts b/build.gradle.kts index 4af21ab..3660bfa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,5 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import java.net.URI val javaVersion = JavaVersion.VERSION_17 val minecraftVersion: String by project @@ -8,6 +9,8 @@ val fabricVersion: String by project val fabricVersionId: String by project val fabricKotlinVersion: String by project val fabricKotlinVersionId: String by project +val completeConfigVersion: String by project +val completeConfigVersionId: String by project val mavenGroup: String by project val modId: String by project val modVersion: String by project @@ -29,7 +32,12 @@ base { archivesName.set(modId) } group = mavenGroup version = modVersion -repositories {} +repositories { + maven { url = URI("https://jitpack.io") } + maven { url = URI("https://maven.terraformersmc.com/") } + maven { url = URI("https://maven.shedaniel.me/") } + maven { url = URI("https://maven.siphalor.de/") } +} dependencies { minecraft("com.mojang", "minecraft", minecraftVersion) @@ -37,6 +45,7 @@ dependencies { modImplementation("net.fabricmc", "fabric-loader", loaderVersion) modImplementation("net.fabricmc.fabric-api", "fabric-api", fabricVersion) modImplementation("net.fabricmc", "fabric-language-kotlin", fabricKotlinVersion) + modImplementation("com.gitlab.Lortseam.completeconfig", "gui-cloth", completeConfigVersion) } tasks { @@ -53,7 +62,7 @@ tasks { processResources { inputs.property("version", project.version) - filesMatching("fabric.mod.json") { expand(mutableMapOf("version" to project.version)) } + filesMatching("fabric.mod.json") { expand(mapOf("version" to project.version)) } } java { @@ -74,6 +83,9 @@ tasks { dependencies { required.version(fabricVersionId) required.version(fabricKotlinVersionId) + required.version(completeConfigVersionId) + optional.project("cloth-config") + optional.project("modmenu") } // syncBodyFrom.set(rootProject.file("README.md").toString()) } diff --git a/changelogs/1.2.0-beta+fabric-1.19.md b/changelogs/1.2.0-beta+fabric-1.19.md new file mode 100644 index 0000000..bd2ceb6 --- /dev/null +++ b/changelogs/1.2.0-beta+fabric-1.19.md @@ -0,0 +1,10 @@ +Now with config! + +**Added**: +- Implement CompleteConfig to allow players to configure levels and limit breaks. +- Configuration UI in game client for single player (using cloth config and mod menu) +- Configuration files in client config directory +- Configuration files in server config directory +- Server configuration synced to client during multiplayer sessions + +**Full Changelog**: https://github.com/eth0net/enchant-menu/compare/v1.1.1+fabric-1.19...v1.2.0-beta+fabric-1.19 diff --git a/gradle.properties b/gradle.properties index b45daf0..8f6298c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,9 +13,12 @@ loomVersion=0.12-SNAPSHOT systemProp.kotlinVersion=1.7.0 fabricKotlinVersion=1.8.2+kotlin.1.7.10 fabricKotlinVersionId=5Aq3SFbi +# Complete Config +completeConfigVersion=2.0.0 +completeConfigVersionId=zaC01d1T # Mod Properties mavenGroup=com.github.eth0net modId=enchant-menu -modVersion=1.1.1+fabric-1.19 -modVersionName=1.1.1 Fabric 1.19 -modVersionType=release +modVersion=1.2.0-beta+fabric-1.19 +modVersionName=1.2.0 Beta Fabric 1.19 +modVersionType=beta diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/EnchantMenu.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/EnchantMenu.kt index b759cfd..dad1e85 100644 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/EnchantMenu.kt +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/EnchantMenu.kt @@ -1,23 +1,41 @@ package com.github.eth0net.enchantmenu +import com.github.eth0net.enchantmenu.config.EnchantMenuConfig import com.github.eth0net.enchantmenu.network.channel.* import com.github.eth0net.enchantmenu.screen.EnchantMenuScreenHandler import com.github.eth0net.enchantmenu.screen.EnchantMenuScreenHandlerFactory -import com.github.eth0net.enchantmenu.util.Identifier -import com.github.eth0net.enchantmenu.util.Logger import net.fabricmc.api.ModInitializer +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking import net.minecraft.screen.ScreenHandlerType +import net.minecraft.util.Identifier import net.minecraft.util.registry.Registry +import org.apache.logging.log4j.LogManager +import java.io.BufferedWriter +import java.io.StringWriter @Suppress("UNUSED") object EnchantMenu : ModInitializer { + internal const val MOD_ID = "enchant-menu" + + internal val log = LogManager.getLogger(MOD_ID) + internal val SCREEN_HANDLER = Registry.register( - Registry.SCREEN_HANDLER, Identifier("enchant_menu"), ScreenHandlerType(::EnchantMenuScreenHandler) + Registry.SCREEN_HANDLER, id("enchant_menu"), ScreenHandlerType(::EnchantMenuScreenHandler) ) override fun onInitialize() { - Logger.info("EnchantMenu initializing...") + log.info("EnchantMenu initializing...") + + EnchantMenuConfig.load() + + ServerPlayConnectionEvents.JOIN.register { net, _, _ -> + val writer = StringWriter() + EnchantMenuConfig.serialize { BufferedWriter(writer) } + val buf = PacketByteBufs.create().writeString(writer.toString()) + ServerPlayNetworking.send(net.player, ConfigSyncChannel, buf) + } ServerPlayNetworking.registerGlobalReceiver(MenuChannel) { _, player, _, _, _ -> player.openHandledScreen(EnchantMenuScreenHandlerFactory) @@ -38,6 +56,8 @@ object EnchantMenu : ModInitializer { (player.currentScreenHandler as? EnchantMenuScreenHandler)?.toggleTreasure() } - Logger.info("EnchantMenu initialized.") + log.info("EnchantMenu initialized.") } + + internal fun id(path: String) = Identifier(MOD_ID, path) } diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/client/EnchantMenuClient.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/client/EnchantMenuClient.kt index 4a3590c..8d11096 100644 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/client/EnchantMenuClient.kt +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/client/EnchantMenuClient.kt @@ -3,18 +3,33 @@ package com.github.eth0net.enchantmenu.client import com.github.eth0net.enchantmenu.EnchantMenu import com.github.eth0net.enchantmenu.client.gui.screen.EnchantMenuScreen import com.github.eth0net.enchantmenu.client.keybinding.MenuKeyBinding +import com.github.eth0net.enchantmenu.config.EnchantMenuConfig +import com.github.eth0net.enchantmenu.network.channel.ConfigSyncChannel import com.github.eth0net.enchantmenu.network.channel.MenuChannel -import com.github.eth0net.enchantmenu.util.Logger +import me.lortseam.completeconfig.gui.ConfigScreenBuilder +import me.lortseam.completeconfig.gui.cloth.ClothConfigScreenBuilder +import me.shedaniel.clothconfig2.api.ConfigBuilder import net.fabricmc.api.ClientModInitializer import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking import net.fabricmc.fabric.api.networking.v1.PacketByteBufs +import net.fabricmc.loader.api.FabricLoader +import net.minecraft.client.MinecraftClient import net.minecraft.client.gui.screen.ingame.HandledScreens +import java.io.BufferedReader +import java.io.StringReader @Suppress("UNUSED") object EnchantMenuClient : ClientModInitializer { override fun onInitializeClient() { - Logger.info("EnchantMenuClient initializing...") + EnchantMenu.log.info("EnchantMenuClient initializing...") + + if (FabricLoader.getInstance().isModLoaded("cloth-config")) { + ConfigScreenBuilder.setMain(EnchantMenu.MOD_ID, ClothConfigScreenBuilder { + val editable = MinecraftClient.getInstance().currentServerEntry == null + ConfigBuilder.create().setEditable(editable) + }) + } HandledScreens.register(EnchantMenu.SCREEN_HANDLER, ::EnchantMenuScreen) @@ -22,6 +37,10 @@ object EnchantMenuClient : ClientModInitializer { while (MenuKeyBinding.wasPressed()) ClientPlayNetworking.send(MenuChannel, PacketByteBufs.empty()) } - Logger.info("EnchantMenuClient initialized.") + ClientPlayNetworking.registerGlobalReceiver(ConfigSyncChannel) { _, _, buf, _ -> + EnchantMenuConfig.deserialize { BufferedReader(StringReader(buf.readString())) } + } + + EnchantMenu.log.info("EnchantMenuClient initialized.") } } diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/client/gui/screen/EnchantMenuScreen.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/client/gui/screen/EnchantMenuScreen.kt index 166d851..45a3e93 100644 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/client/gui/screen/EnchantMenuScreen.kt +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/client/gui/screen/EnchantMenuScreen.kt @@ -1,9 +1,10 @@ package com.github.eth0net.enchantmenu.client.gui.screen +import com.github.eth0net.enchantmenu.EnchantMenu import com.github.eth0net.enchantmenu.client.keybinding.* +import com.github.eth0net.enchantmenu.config.EnchantMenuConfig import com.github.eth0net.enchantmenu.network.channel.* import com.github.eth0net.enchantmenu.screen.EnchantMenuScreenHandler -import com.github.eth0net.enchantmenu.util.Identifier import com.mojang.blaze3d.systems.RenderSystem import net.fabricmc.api.EnvType import net.fabricmc.api.Environment @@ -26,7 +27,7 @@ class EnchantMenuScreen(handler: EnchantMenuScreenHandler, playerInventory: Play override fun getDisplayName() = Text.empty() }, title) { - private val texture = Identifier("textures/gui/enchant_menu.png") + private val texture = EnchantMenu.id("textures/gui/enchant_menu.png") private var stack = ItemStack.EMPTY private var ticks = 0 @@ -106,10 +107,10 @@ class EnchantMenuScreen(handler: EnchantMenuScreenHandler, playerInventory: Play // level change buttons clearChildren() - if (handler.level < handler.maxLevel) addDrawableChild(TexturedButtonWidget( + if (handler.level < EnchantMenuConfig.Levels.maximum) addDrawableChild(TexturedButtonWidget( x + 31, y + 18, 8, 13, 149, 166, texture ) { onIncrementLevelClick() }) - if (handler.level > handler.minLevel) addDrawableChild(TexturedButtonWidget( + if (handler.level > EnchantMenuConfig.Levels.minimum) addDrawableChild(TexturedButtonWidget( x + 6, y + 18, 8, 13, 141, 166, texture ) { onDecrementLevelClick() }) @@ -122,13 +123,13 @@ class EnchantMenuScreen(handler: EnchantMenuScreenHandler, playerInventory: Play } // limit breaks - addDrawableChild(TexturedButtonWidget( + if (EnchantMenuConfig.AllowLimitBreaks.incompatible) addDrawableChild(TexturedButtonWidget( x + 152, y + 5, 11, 11, 168, if (handler.incompatibleUnlocked) 177 else 166, texture ) { onToggleIncompatibleClick() }) - addDrawableChild(TexturedButtonWidget( + if (EnchantMenuConfig.AllowLimitBreaks.level) addDrawableChild(TexturedButtonWidget( x + 165, y + 5, 11, 11, 179, if (handler.levelUnlocked) 177 else 166, texture ) { onToggleLevelClick() }) - addDrawableChild(TexturedButtonWidget( + if (EnchantMenuConfig.AllowLimitBreaks.treasure) addDrawableChild(TexturedButtonWidget( x + 178, y + 5, 11, 11, 190, if (handler.treasureUnlocked) 177 else 166, texture ) { onToggleTreasureClick() }) diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/config/EnchantMenuConfig.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/config/EnchantMenuConfig.kt new file mode 100644 index 0000000..2ce034c --- /dev/null +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/config/EnchantMenuConfig.kt @@ -0,0 +1,98 @@ +package com.github.eth0net.enchantmenu.config + +import com.github.eth0net.enchantmenu.EnchantMenu +import me.lortseam.completeconfig.api.ConfigContainer +import me.lortseam.completeconfig.api.ConfigContainer.Transitive +import me.lortseam.completeconfig.api.ConfigEntries +import me.lortseam.completeconfig.api.ConfigEntry +import me.lortseam.completeconfig.api.ConfigEntry.BoundedInteger +import me.lortseam.completeconfig.api.ConfigEntry.Slider +import me.lortseam.completeconfig.api.ConfigGroup +import me.lortseam.completeconfig.data.Config + +object EnchantMenuConfig : Config(EnchantMenu.MOD_ID), ConfigContainer { + @Transitive + @ConfigEntries(includeAll = true) + object Levels : ConfigGroup { + @BoundedInteger(min = 1, max = 100) + @Slider + var minimum = 1 + set(value) { + field = if (value < 1) { + 1 + } else if (value > maximum) { + maximum + } else { + value + } + } + + @BoundedInteger(min = 1, max = 100) + @Slider + var maximum = 10 + set(value) { + field = if (value < minimum) { + minimum + } else if (value > 100) { + 100 + } else { + value + } + } + + @BoundedInteger(min = 1, max = 100) + @Slider + var default = minimum + set(value) { + field = if (value < minimum) { + minimum + } else if (value > maximum) { + maximum + } else { + value + } + } + } + + @Transitive + object AllowLimitBreaks : ConfigGroup { + @ConfigEntry + var incompatible = true + fun toggleIncompatible() { + incompatible = !incompatible + } + + @ConfigEntry + var level = true + fun toggleLevel() { + level = !level + } + + @ConfigEntry + var treasure = true + fun toggleTreasure() { + treasure = !treasure + } + } + + @Transitive + object AutoLimitBreaks : ConfigGroup { + @ConfigEntry + var incompatible = false + fun toggleIncompatible() { + incompatible = !incompatible + } + + @ConfigEntry + var level = false + fun toggleLevel() { + level = !level + } + + @ConfigEntry + var treasure = false + fun toggleTreasure() { + treasure = !treasure + } + } +} diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/network/channel/Channel.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/network/channel/Channel.kt index 8d4ea25..1f100f7 100644 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/network/channel/Channel.kt +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/network/channel/Channel.kt @@ -1,10 +1,11 @@ package com.github.eth0net.enchantmenu.network.channel -import com.github.eth0net.enchantmenu.util.Identifier +import com.github.eth0net.enchantmenu.EnchantMenu.id -internal val MenuChannel = Identifier("toggle_menu_channel") -internal val DecrementLevelChannel = Identifier("decrement_level_channel") -internal val IncrementLevelChannel = Identifier("increment_level_channel") -internal val ToggleIncompatibleChannel = Identifier("toggle_incompatible_channel") -internal val ToggleLevelChannel = Identifier("toggle_level_channel") -internal val ToggleTreasureChannel = Identifier("toggle_treasure_channel") +internal val MenuChannel = id("toggle_menu_channel") +internal val ConfigSyncChannel = id("config_sync_channel") +internal val DecrementLevelChannel = id("decrement_level_channel") +internal val IncrementLevelChannel = id("increment_level_channel") +internal val ToggleIncompatibleChannel = id("toggle_incompatible_channel") +internal val ToggleLevelChannel = id("toggle_level_channel") +internal val ToggleTreasureChannel = id("toggle_treasure_channel") diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/screen/EnchantMenuScreenHandler.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/screen/EnchantMenuScreenHandler.kt index 69e22a2..1beddc1 100644 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/screen/EnchantMenuScreenHandler.kt +++ b/src/main/kotlin/com/github/eth0net/enchantmenu/screen/EnchantMenuScreenHandler.kt @@ -1,10 +1,10 @@ package com.github.eth0net.enchantmenu.screen import com.github.eth0net.enchantmenu.EnchantMenu +import com.github.eth0net.enchantmenu.config.EnchantMenuConfig import com.github.eth0net.enchantmenu.screen.slot.ArmorSlot import com.github.eth0net.enchantmenu.screen.slot.EnchantSlot import com.github.eth0net.enchantmenu.screen.slot.OffhandSlot -import com.github.eth0net.enchantmenu.util.Logger import net.minecraft.enchantment.Enchantment import net.minecraft.enchantment.EnchantmentHelper import net.minecraft.entity.player.PlayerEntity @@ -36,24 +36,27 @@ class EnchantMenuScreenHandler( } } - internal val minLevel = 1 - internal val maxLevel = 10 - internal var level = minLevel + internal var enchantments: List> = listOf() + + internal var level = EnchantMenuConfig.Levels.default set(value) { - field = if (value < minLevel) { - minLevel - } else if (value > maxLevel) { - maxLevel + field = if (value < EnchantMenuConfig.Levels.minimum) { + EnchantMenuConfig.Levels.minimum + } else if (value > EnchantMenuConfig.Levels.maximum) { + EnchantMenuConfig.Levels.maximum } else { value } } - internal var enchantments: List> = listOf() + internal var incompatibleUnlocked = EnchantMenuConfig.AutoLimitBreaks.incompatible + get() = EnchantMenuConfig.AllowLimitBreaks.incompatible && field + + internal var levelUnlocked = EnchantMenuConfig.AutoLimitBreaks.level + get() = EnchantMenuConfig.AllowLimitBreaks.level && field - internal var incompatibleUnlocked = false - internal var levelUnlocked = false - internal var treasureUnlocked = false + internal var treasureUnlocked = EnchantMenuConfig.AutoLimitBreaks.treasure + get() = EnchantMenuConfig.AllowLimitBreaks.treasure && field init { addSlot(EnchantSlot(inventory, 0, 15, 40)) @@ -70,7 +73,7 @@ class EnchantMenuScreenHandler( override fun onButtonClick(player: PlayerEntity, id: Int): Boolean { if (id !in enchantments.indices) { - Logger.error("${player.name} tried to press invalid button $id") + EnchantMenu.log.error("${player.name} tried to press invalid button $id") return false } @@ -183,11 +186,11 @@ class EnchantMenuScreenHandler( } internal fun incrementLevel() { - if (level < maxLevel) ++level + if (level < EnchantMenuConfig.Levels.maximum) ++level } internal fun decrementLevel() { - if (level > minLevel) --level + if (level > EnchantMenuConfig.Levels.minimum) --level } internal fun toggleIncompatible() { diff --git a/src/main/kotlin/com/github/eth0net/enchantmenu/util/Util.kt b/src/main/kotlin/com/github/eth0net/enchantmenu/util/Util.kt deleted file mode 100644 index 953f29e..0000000 --- a/src/main/kotlin/com/github/eth0net/enchantmenu/util/Util.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.github.eth0net.enchantmenu.util - -import net.minecraft.util.Identifier -import org.apache.logging.log4j.LogManager - -internal const val MOD_ID = "enchant-menu" - -internal val Logger = LogManager.getLogger(MOD_ID) - -internal fun Identifier(path: String) = Identifier(MOD_ID, path) diff --git a/src/main/resources/assets/enchant-menu/lang/en_us.json b/src/main/resources/assets/enchant-menu/lang/en_us.json index fa51290..0670e0d 100644 --- a/src/main/resources/assets/enchant-menu/lang/en_us.json +++ b/src/main/resources/assets/enchant-menu/lang/en_us.json @@ -1,6 +1,18 @@ { "enchant-menu.title": "Enchant Menu", "category.enchant-menu.general": "Enchant Menu", + "config.enchant-menu.levels": "Levels", + "config.enchant-menu.levels.minimum": "Minimum Level", + "config.enchant-menu.levels.maximum": "Maximum Level", + "config.enchant-menu.levels.default": "Default Level", + "config.enchant-menu.allowLimitBreaks": "Allow Limit Breaks", + "config.enchant-menu.allowLimitBreaks.incompatible": "Allow Incompatible", + "config.enchant-menu.allowLimitBreaks.level": "Allow Level", + "config.enchant-menu.allowLimitBreaks.treasure": "Allow Treasure", + "config.enchant-menu.autoLimitBreaks": "Auto Limit Breaks", + "config.enchant-menu.autoLimitBreaks.incompatible": "Auto-enable Incompatible", + "config.enchant-menu.autoLimitBreaks.level": "Auto-enable Level", + "config.enchant-menu.autoLimitBreaks.treasure": "Auto-enable Treasure", "key.enchant-menu.menu": "Toggle Enchant Menu", "key.enchant-menu.increment_level": "Increment Level", "key.enchant-menu.decrement_level": "Decrement Level", diff --git a/src/main/resources/assets/enchant-menu/textures/gui/enchant_menu.png b/src/main/resources/assets/enchant-menu/textures/gui/enchant_menu.png index bc29cef..ee4f7f9 100644 Binary files a/src/main/resources/assets/enchant-menu/textures/gui/enchant_menu.png and b/src/main/resources/assets/enchant-menu/textures/gui/enchant_menu.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index b73d82f..d89cfd5 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -34,7 +34,12 @@ "fabricloader": ">=0.14.8", "fabric": "*", "fabric-language-kotlin": ">=1.8.2+kotlin.1.7.10", + "completeconfig": "^2.0.0", "minecraft": "1.19.x", "java": ">=17" + }, + "recommends": { + "cloth-config": "*", + "modmenu": "*" } }