From 900abe2d60004d759aeb07e6edddb0d86588e66f Mon Sep 17 00:00:00 2001 From: ManApart Date: Thu, 4 Jan 2024 08:08:37 -0500 Subject: [PATCH] wip esp reordering --- src/main/kotlin/commands/CommandType.kt | 1 + src/main/kotlin/commands/Esps.kt | 103 ++++++++++++++++++++++++ src/main/kotlin/commands/Order.kt | 5 +- 3 files changed, 107 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/commands/Esps.kt diff --git a/src/main/kotlin/commands/CommandType.kt b/src/main/kotlin/commands/CommandType.kt index a54e022..09240e3 100644 --- a/src/main/kotlin/commands/CommandType.kt +++ b/src/main/kotlin/commands/CommandType.kt @@ -22,6 +22,7 @@ enum class CommandType( LIST("List Mods", Category.VIEW, listDescription, listUsage, ::listMods, "ls"), DETAIL("View all details of mod", Category.VIEW, detailDescription, detailUsage, ::detailMod), ORDER("Change Load Order", Category.DEPLOY, orderDescription, orderUsage, ::order), + ESP("Change Load Order for plugins", Category.DEPLOY, espDescription, espUsage, ::esp, "esps", "plugin", "plugins"), OPEN("Open mod on web", Category.OPEN, openDescription, "open ", ::open), LOCAL("Open local mod folder", Category.OPEN, openDescription, "local ", ::local), GAME_PATH("Open game folder", Category.OPEN, openDescription, "", ::openGamePath, "gamepath"), diff --git a/src/main/kotlin/commands/Esps.kt b/src/main/kotlin/commands/Esps.kt new file mode 100644 index 0000000..7d0c131 --- /dev/null +++ b/src/main/kotlin/commands/Esps.kt @@ -0,0 +1,103 @@ +package commands + +import Column +import Mod +import Table +import clearConsole +import toolData +import java.io.File + +val espDescription = """ + Plugins with a higher load order are loaded later, and override plugins loaded earlier. Given plugin A has an order 5 and plugin B has an order of 1, then A will load AFTER B, and A's records will be used instead of B's in any conflicts. + In these examples the first number is the mod index and the second is the sort order you want + esp ls - view load order of plugins + esp 1 set 4 - sets mod with index 1 to load order 4. Any plugins with a higher number for load order have their number increased + esp 1 later - sets the plugin to load after the next plugin (may shift the order number more than one as it shifts until it's after the next plugin). + esp 1 later 2 - same as above but shifts down by two plugins + For general mod order, see order command. The same order number is used for both commands. +""".trimIndent() + +val espUsage = """ + esp ls + esp 1 first + esp 1 last + esp 1 sooner 5 + esp 1 later + esp 1 set 4 +""".trimIndent() + +fun esp(args: List) { + val arguments = parseArgs(args) + ?: if (args.size == 1 && args.last() == "ls") { + display(getModsWithPlugins()) + return + } else { + println(orderDescription) + return + } + with(arguments) { + val mods = getModsWithPlugins() + when { + subCommand == "first" -> setModOrder(toolData.mods, index, 0) + subCommand == "last" -> setModOrder(toolData.mods, index, toolData.nextLoadOrder()) + subCommand == "set" && amount != null -> setModOrder(toolData.mods, index, amount) + subCommand == "sooner" && amount != null -> setModOrder( + toolData.mods, + index, + nextPluginIndex(mods, index, -amount) + ) + + subCommand == "later" && amount != null -> setModOrder( + toolData.mods, + index, + nextPluginIndex(mods, index, amount) + ) + + subCommand == "sooner" -> setModOrder(toolData.mods, index, nextPluginIndex(mods, index, -1)) + subCommand == "later" -> setModOrder(toolData.mods, index, nextPluginIndex(mods, index, 1)) + else -> println("Unknown subCommand: ") + } + display(getModsWithPlugins()) + } +} + +private fun getModsWithPlugins(): Map> { + val espTypes = listOf("esp", "esm", "esl") + return toolData.mods + .filter { it.enabled }.sortedBy { it.loadOrder } + .associateWith { mod -> mod.getModFiles().filter { it.extension.lowercase() in espTypes } } + .filter { (_, files) -> files.isNotEmpty() } +} + +private typealias NewModIndex = Int + +private fun nextPluginIndex(mods: Map>, modIndexToShift: Int, pluginShiftAmount: Int): NewModIndex { + val sortedMods = mods.keys.toList().sortedBy { it.loadOrder } + val i = sortedMods.firstOrNull { it.index == modIndexToShift }?.let { sortedMods.indexOf(it) } ?: -1 + val mod = sortedMods.getOrNull(i + pluginShiftAmount) + return mod?.index ?: -1 +} + +private fun display(mods: Map>) { + clearConsole() + val columns = listOf( + Column("Id", 7), + Column("Load", 7, true), + Column("Index", 7, true), + Column("Esp", 30), + Column("Mod", 22), + ) + val data = mods.flatMap { (mod, files) -> files.map { mod to it } }.map { (mod, file) -> + with(mod) { + val idClean = id?.toString() ?: "?" + mapOf( + "Index" to mod.index, + "Load" to loadOrder, + "Id" to idClean, + "Esp" to file.name, + "Mod" to name, + ) + } + } + Table(columns, data).print() +} \ No newline at end of file diff --git a/src/main/kotlin/commands/Order.kt b/src/main/kotlin/commands/Order.kt index 1824dd7..ff48748 100644 --- a/src/main/kotlin/commands/Order.kt +++ b/src/main/kotlin/commands/Order.kt @@ -9,6 +9,7 @@ val orderDescription = """ In these examples the first number is the mod index and the second is the sort order you want order 1 set 4 - sets mod with index 1 to load order 4. Any mods with a higher number for load order have their number increased order 1 - view any conflicts mod index 1 has with any other mods + To manage load order specifically for plugins, see esps command. The same order number is used for both commands. """.trimIndent() val orderUsage = """ @@ -20,7 +21,7 @@ val orderUsage = """ order 1 set 4 """.trimIndent() -private data class Args(val index: Int, val subCommand: String, val amount: Int?) +data class Args(val index: Int, val subCommand: String, val amount: Int?) fun order(args: List) { val arguments = parseArgs(args) @@ -45,7 +46,7 @@ fun order(args: List) { } } -private fun parseArgs(args: List): Args? { +fun parseArgs(args: List): Args? { val index = args.getOrNull(0)?.toIntOrNull() val subCommand = args.getOrNull(1) val amount = args.getOrNull(2)?.toIntOrNull()