From 068d0bf1b2fefcba7377f2ef7177064299be8bb8 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 7 Feb 2026 16:19:42 +0900 Subject: [PATCH] control preset to be stored into separate file --- src/net/torvald/terrarum/App.java | 21 ++ .../torvald/terrarum/ControlPresetConfig.kt | 229 ++++++++++++++++++ src/net/torvald/terrarum/ControlPresets.kt | 26 +- src/net/torvald/terrarum/DefaultConfig.kt | 35 +-- src/net/torvald/terrarum/Terrarum.kt | 4 +- .../gamecontroller/IngameController.kt | 6 +- .../terrarum/modulebasegame/BuildingMaker.kt | 4 +- .../terrarum/modulebasegame/TitleScreen.kt | 2 +- .../modulebasegame/gameitems/BlockBase.kt | 2 +- .../modulebasegame/gameitems/ItemWrench.kt | 4 +- .../ui/SmelterGuiEventBuilder.kt | 16 +- .../modulebasegame/ui/UIAlloyingFurnace.kt | 4 +- .../ui/UIItemInventoryItemGrid.kt | 2 +- .../modulebasegame/ui/UIJukeboxInventory.kt | 4 +- .../ui/UIKeyboardControlPanel.kt | 24 +- .../modulebasegame/ui/UISmelterBasic.kt | 4 +- .../modulebasegame/ui/UIStorageChest.kt | 12 +- .../modulebasegame/ui/UIWorldPortalCargo.kt | 4 +- .../torvald/terrarum/serialise/WriteConfig.kt | 12 +- src/net/torvald/terrarum/ui/ConsoleWindow.kt | 4 +- src/net/torvald/terrarum/ui/MouseLatch.kt | 2 +- src/net/torvald/terrarum/ui/UIItem.kt | 2 +- 22 files changed, 336 insertions(+), 87 deletions(-) create mode 100644 src/net/torvald/terrarum/ControlPresetConfig.kt diff --git a/src/net/torvald/terrarum/App.java b/src/net/torvald/terrarum/App.java index eba223263..6db30b032 100644 --- a/src/net/torvald/terrarum/App.java +++ b/src/net/torvald/terrarum/App.java @@ -447,6 +447,15 @@ public class App implements ApplicationListener { createDirs(); initialiseConfig(); readConfigJson(); + + // Initialise control preset config (separate from main config) + ControlPresetConfig.initialise(); + // Migrate control settings on first run with new system + File controlsFile = new File(controlPresetDir); + if (!controlsFile.exists()) { + ControlPresetConfig.migrateFromGenericConfig(); + } + setGamepadButtonLabels(); rectifyConfigs(); @@ -1487,6 +1496,8 @@ public class App implements ApplicationListener { public static String worldsDir; /** defaultDir + "/config.json" */ public static String configDir; + /** defaultDir + "/controls.json" */ + public static String controlPresetDir; /** defaultDir + "/LoadOrder.txt" */ public static String loadOrderDir; /** defaultDir + "/Imported" */ @@ -1532,6 +1543,7 @@ public class App implements ApplicationListener { playersDir = defaultDir + "/Players"; worldsDir = defaultDir + "/Worlds"; configDir = defaultDir + "/config.json"; + controlPresetDir = defaultDir + "/controls.json"; loadOrderDir = defaultDir + "/LoadOrder.txt"; recycledPlayersDir = defaultDir + "/Recycled/Players"; recycledWorldsDir = defaultDir + "/Recycled/Worlds"; @@ -1806,6 +1818,15 @@ public class App implements ApplicationListener { public static Object getConfigMaster(String key1) { String key = key1.toLowerCase(); + // Delegate control_key_*, control_mouse_*, control_preset_keyboard to ControlPresetConfig + if (ControlPresetConfig.isControlKey(key)) { + Object result = ControlPresetConfig.get(key); + if (result != null) { + return result; + } + // Fall through to check defaults if ControlPresetConfig doesn't have it + } + Object config; try { config = gameConfig.get(key); diff --git a/src/net/torvald/terrarum/ControlPresetConfig.kt b/src/net/torvald/terrarum/ControlPresetConfig.kt new file mode 100644 index 000000000..0905bf4a5 --- /dev/null +++ b/src/net/torvald/terrarum/ControlPresetConfig.kt @@ -0,0 +1,229 @@ +package net.torvald.terrarum + +import com.badlogic.gdx.Input +import com.badlogic.gdx.utils.Json +import com.badlogic.gdx.utils.JsonValue +import com.badlogic.gdx.utils.JsonWriter +import net.torvald.terrarum.utils.JsonFetcher +import java.io.File +import java.io.FileWriter + +/** + * Holds and manages the control preset configuration separately from the main config. + * This allows users to easily share their control configurations via controls.json. + * + * Modules can register custom control labels using [registerModuleControl]. + * + * Created by minjaesong on 2026-02-03. + */ +object ControlPresetConfig { + + private val configMap = KVHashMap() + private val jsoner = Json(JsonWriter.OutputType.json) + + // Default values for built-in controls + private val defaults = hashMapOf( + "control_preset_keyboard" to "WASD", + + // Keyboard controls (ESDF defaults matching DefaultConfig) + "control_key_up" to Input.Keys.E, + "control_key_left" to Input.Keys.S, + "control_key_down" to Input.Keys.D, + "control_key_right" to Input.Keys.F, + "control_key_jump" to Input.Keys.SPACE, + "control_key_movementaux" to Input.Keys.A, + "control_key_inventory" to Input.Keys.Q, + "control_key_interact" to Input.Keys.R, + "control_key_discard" to Input.Keys.T, + "control_key_close" to Input.Keys.C, + "control_key_zoom" to Input.Keys.Z, + "control_key_gamemenu" to Input.Keys.TAB, + "control_key_crafting" to Input.Keys.W, + "control_key_quicksel" to Input.Keys.SHIFT_LEFT, + "control_key_toggleime" to Input.Keys.ALT_RIGHT, + + // Mouse controls + "control_mouse_primary" to Input.Buttons.LEFT, + "control_mouse_secondary" to Input.Buttons.RIGHT, + "control_mouse_quicksel" to Input.Buttons.MIDDLE, + + // Array-type controls + "control_key_quickslots" to ((Input.Keys.NUM_1..Input.Keys.NUM_9) + arrayOf(Input.Keys.NUM_0)).map { 1.0 * it }.toDoubleArray(), + "control_key_quickselalt" to intArrayOf(Input.Keys.BACKSPACE, Input.Keys.CONTROL_LEFT, Input.Keys.BACKSLASH).map { 1.0 * it }.toDoubleArray(), + ) + + init { + // Set up JSON serialiser for KVHashMap + jsoner.ignoreUnknownFields = true + jsoner.setUsePrototypes(false) + jsoner.setIgnoreDeprecated(false) + jsoner.setSerializer(KVHashMap::class.java, object : Json.Serializer { + override fun write(json: Json, obj: KVHashMap, knownType: Class<*>?) { + json.writeObjectStart() + obj.hashMap.toSortedMap().forEach { (k, v) -> + json.writeValue(k, v) + } + json.writeObjectEnd() + } + + override fun read(json: Json, jsonData: JsonValue, type: Class<*>?): KVHashMap { + val map = KVHashMap() + JsonFetcher.forEachSiblings(jsonData) { key, obj -> + map[key] = json.readValue(null, obj) + } + return map + } + }) + } + + /** + * Initialises the control preset config with defaults, then loads from file. + * Should be called during App initialisation, BEFORE modules load. + */ + @JvmStatic + fun initialise() { + // Populate with defaults + defaults.forEach { (k, v) -> configMap[k] = v } + + // Load from file if exists + loadFromFile() + } + + /** + * Registers a custom control for a module. + * @param moduleName The module's identifier (directory name) + * @param device One of "key", "mouse" (not "gamepad") + * @param label The control label (e.g., "special_action") + * @param defaultValue The default key/button code + */ + fun registerModuleControl(moduleName: String, device: String, label: String, defaultValue: Int) { + require(device in listOf("key", "mouse")) { "Device must be 'key' or 'mouse', got '$device'" } + val key = "${moduleName}:control_${device}_$label" + if (!configMap.hasKey(key)) { + configMap[key] = defaultValue + } + } + + /** + * Returns true if this key should be handled by ControlPresetConfig instead of App.gameConfig + */ + @JvmStatic + fun isControlKey(key: String): Boolean { + val k = key.lowercase() + return k.startsWith("control_key_") || k.startsWith("control_mouse_") || k == "control_preset_keyboard" || + (k.contains(":control_key_") || k.contains(":control_mouse_")) + } + + @JvmStatic + fun getString(key: String): String? = configMap.getAsString(key.lowercase()) ?: defaults[key.lowercase()] as? String + + @JvmStatic + fun getInt(key: String): Int { + val k = key.lowercase() + val value = configMap[k] ?: defaults[k] + return when (value) { + is Int -> value + is Double -> value.toInt() + else -> -1 + } + } + + @JvmStatic + fun getIntArray(key: String): IntArray { + val k = key.lowercase() + val arr = configMap[k] ?: defaults[k] + return when (arr) { + is DoubleArray -> arr.map { it.toInt() }.toIntArray() + is IntArray -> arr + else -> intArrayOf() + } + } + + @JvmStatic + fun getDoubleArray(key: String): DoubleArray { + val k = key.lowercase() + val arr = configMap[k] ?: defaults[k] + return when (arr) { + is DoubleArray -> arr + is IntArray -> arr.map { it.toDouble() }.toDoubleArray() + else -> doubleArrayOf() + } + } + + @JvmStatic + fun get(key: String): Any? { + val k = key.lowercase() + return configMap[k] ?: defaults[k] + } + + @JvmStatic + fun set(key: String, value: Any) { + configMap[key.lowercase()] = value + } + + fun containsKey(key: String): Boolean { + val k = key.lowercase() + return configMap.hasKey(k) || defaults.containsKey(k) + } + + /** + * Returns the key set of configured controls (excludes defaults not yet written) + */ + val keySet: Set + get() = configMap.keySet + + private fun loadFromFile() { + val file = File(App.controlPresetDir) + if (!file.exists()) return + + try { + val json = JsonFetcher(App.controlPresetDir) + var entry: JsonValue? = json.child + while (entry != null) { + configMap[entry.name] = when { + entry.isArray -> entry.asDoubleArray() + entry.isDouble -> entry.asDouble() + entry.isBoolean -> entry.asBoolean() + entry.isLong -> entry.asInt() + else -> entry.asString() + } + entry = entry.next + } + } catch (e: Exception) { + System.err.println("[ControlPresetConfig] Failed to load controls.json: ${e.message}") + } + } + + @JvmStatic + fun save() { + try { + val writer = FileWriter(App.controlPresetDir, false) + writer.write(jsoner.prettyPrint(configMap)) + writer.close() + } catch (e: Exception) { + System.err.println("[ControlPresetConfig] Failed to save controls.json: ${e.message}") + } + } + + /** + * Migrates control settings from App.gameConfig to this config. + * Called once during first run with new system. + */ + @JvmStatic + fun migrateFromGenericConfig() { + val keysToMigrate = App.gameConfig.keySet.filter { key -> + val k = (key as String).lowercase() + k.startsWith("control_key_") || k.startsWith("control_mouse_") || k == "control_preset_keyboard" + } + + if (keysToMigrate.isEmpty()) return + + keysToMigrate.forEach { key -> + val k = key as String + configMap[k] = App.gameConfig[k]!! + } + + save() + println("[ControlPresetConfig] Migrated ${keysToMigrate.size} control settings from config.json") + } +} diff --git a/src/net/torvald/terrarum/ControlPresets.kt b/src/net/torvald/terrarum/ControlPresets.kt index 9689eb353..9f8a93455 100644 --- a/src/net/torvald/terrarum/ControlPresets.kt +++ b/src/net/torvald/terrarum/ControlPresets.kt @@ -3,6 +3,8 @@ package net.torvald.terrarum import com.badlogic.gdx.Input /** + * For mod authors: use `registerPreset()` to register new preset. This must be done on your [ModuleEntryPoint] + * * Created by minjaesong on 2023-08-24. */ object ControlPresets { @@ -23,7 +25,7 @@ object ControlPresets { "control_key_gamemenu" to Input.Keys.TAB, "control_key_crafting" to Input.Keys.F, - "control_key_quicksel" to Input.Keys.CONTROL_LEFT, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input + "control_key_quicksel" to Input.Keys.CONTROL_LEFT, // pie menu is now LShift because CapsLock is actually used by my bespoke keyboard input ) val esdf = hashMapOf( @@ -42,7 +44,7 @@ object ControlPresets { "control_key_gamemenu" to Input.Keys.TAB, "control_key_crafting" to Input.Keys.W, - "control_key_quicksel" to Input.Keys.SHIFT_LEFT, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input + "control_key_quicksel" to Input.Keys.SHIFT_LEFT, // pie menu is now LShift because CapsLock is actually used by my bespoke keyboard input ) val ijkl = hashMapOf( @@ -61,7 +63,7 @@ object ControlPresets { "control_key_gamemenu" to Input.Keys.LEFT_BRACKET, "control_key_crafting" to Input.Keys.O, - "control_key_quicksel" to Input.Keys.APOSTROPHE, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input + "control_key_quicksel" to Input.Keys.APOSTROPHE, // pie menu is now LShift because CapsLock is actually used by my bespoke keyboard input ) val empty = hashMapOf() @@ -73,19 +75,31 @@ object ControlPresets { "Custom" to empty, ) - val presetLabels = listOf( // ordered + val presetLabels = mutableListOf( // ordered "WASD", "ESDF", "IJKL", "Custom", ) + /** + * Retrieves a keycode assigned to the action given as `label`, using currently active preset (`ControlPresetConfig.getString("control_preset_keyboard")`) as a reference. + * + * If `ControlPresetConfig.getString("control_preset_keyboard")` evaluates to `null`, preset "Custom" will be referenced instead. + * + * @throws IllegalStateException if for some reason the currently active preset is not a known one + */ fun getKey(label: String?): Int { if (label == null) return -1 - val presetName = App.getConfigString("control_preset_keyboard") ?: "Custom" + val presetName = ControlPresetConfig.getString("control_preset_keyboard") ?: "Custom" - return (presets[presetName] ?: throw IllegalStateException("No such keyboard preset: $presetName")).getOrDefault(label, App.getConfigInt(label)) + return (presets[presetName] ?: throw IllegalStateException("No such keyboard preset: $presetName")).getOrDefault(label, ControlPresetConfig.getInt(label)) + } + + fun registerPreset(label: String, keymap: HashMap) { + presets[label] = keymap + presetLabels.addLast(label) } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/DefaultConfig.kt b/src/net/torvald/terrarum/DefaultConfig.kt index 3c19611dd..17d9ca390 100644 --- a/src/net/torvald/terrarum/DefaultConfig.kt +++ b/src/net/torvald/terrarum/DefaultConfig.kt @@ -37,7 +37,7 @@ object DefaultConfig { "usexinput" to true, // when FALSE, LT+RT input on xbox controller is impossible - "control_preset_keyboard" to "WASD", + // control_preset_keyboard now lives in ControlPresetConfig (controls.json) "control_gamepad_keyn" to 3, "control_gamepad_keyw" to 2, @@ -65,38 +65,9 @@ object DefaultConfig { // to accomodate shifted zero point of analog stick "control_gamepad_axiszeropoints" to doubleArrayOf(0.0,0.0,0.0,0.0), - "control_gamepad_labelstyle" to "msxbone", // "nwii", "logitech", "sonyps", "msxb360", "msxbone" - - // control-keyboard (GDX key codes, - "control_key_up" to Input.Keys.E, - "control_key_left" to Input.Keys.S, - "control_key_down" to Input.Keys.D, - "control_key_right" to Input.Keys.F, // ESDF Masterrace - - "control_key_jump" to Input.Keys.SPACE, - "control_key_movementaux" to Input.Keys.A, // movement-auxiliary, or hookshot - "control_key_inventory" to Input.Keys.Q, - "control_key_interact" to Input.Keys.R, - "control_key_discard" to Input.Keys.T, - "control_key_close" to Input.Keys.C, // this or hard-coded ESC - "control_key_zoom" to Input.Keys.Z, - - "control_key_gamemenu" to Input.Keys.TAB, - "control_key_crafting" to Input.Keys.W, - "control_key_quicksel" to Input.Keys.SHIFT_LEFT, // pie menu is now LShift because CapsLock is actually used by the my bespoke keyboard input - "control_mouse_quicksel" to Input.Buttons.MIDDLE, // middle click to open pie menu - - // Colemak, Workman and some typers use CapsLock as Backspace, Apple-JIS and HHKB has Control in place of CapsLock and often re-assigned to Command - // so these keys are treated as the same. - // FOR ~~FUCKS~~ERGONOMICS' SAKE DON'T USE CTRL AND ALT AS A KEY! - "control_key_quickslots" to ((Input.Keys.NUM_1..Input.Keys.NUM_9) + arrayOf(Input.Keys.NUM_0)).map { 1.0*it }.toDoubleArray(), - "control_key_quickselalt" to intArrayOf(Input.Keys.BACKSPACE, Input.Keys.CONTROL_LEFT, Input.Keys.BACKSLASH).map { 1.0*it }.toDoubleArray(), - - "control_key_toggleime" to Input.Keys.ALT_RIGHT, - - "config_mouseprimary" to Input.Buttons.LEFT, // left mouse - "config_mousesecondary" to Input.Buttons.RIGHT, // right mouse + "control_gamepad_labelstyle" to "msxbone", // "nintendo", "logitech", "sony", "msxb360", "msxbone" + // control_key_*, control_mouse_* entries now live in ControlPresetConfig (controls.json) "pcgamepadenv" to "console", diff --git a/src/net/torvald/terrarum/Terrarum.kt b/src/net/torvald/terrarum/Terrarum.kt index a47f80c1c..cef550b98 100644 --- a/src/net/torvald/terrarum/Terrarum.kt +++ b/src/net/torvald/terrarum/Terrarum.kt @@ -269,9 +269,9 @@ object Terrarum : Disposable { inline val updateRate: Double get() = 1.0 / Gdx.graphics.deltaTime val mouseDown: Boolean - get() = Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary")) + get() = Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_primary")) val mouseJustDown: Boolean - get() = Gdx.input.isButtonJustPressed(App.getConfigInt("config_mouseprimary")) + get() = Gdx.input.isButtonJustPressed(App.getConfigInt("control_mouse_primary")) val mouseOnPlayer: Boolean get() = ingame?.actorNowPlaying?.mouseUp ?: false diff --git a/src/net/torvald/terrarum/gamecontroller/IngameController.kt b/src/net/torvald/terrarum/gamecontroller/IngameController.kt index 11562b9bc..9177f8c27 100644 --- a/src/net/torvald/terrarum/gamecontroller/IngameController.kt +++ b/src/net/torvald/terrarum/gamecontroller/IngameController.kt @@ -145,7 +145,7 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() { terrarumIngame.worldPrimaryClickStart(actor, App.UPDATE_RATE) worldPrimaryClickLatched = true } - if (actor != null && Gdx.input.isButtonPressed(App.getConfigInt("config_mousesecondary"))) { + if (actor != null && Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_secondary"))) { terrarumIngame.worldSecondaryClickStart(actor, App.UPDATE_RATE) } @@ -258,10 +258,10 @@ class IngameController(val terrarumIngame: TerrarumIngame) : InputAdapter() { // fire world click events; the event is defined as Ingame's (or any others') WorldClick event // if (terrarumIngame.uiContainer.map { if ((it?.isOpening == true || it?.isOpened == true) && it.mouseUp) 1 else 0 }.sum() == 0) { // no UI on the mouse, right? - if (button == App.getConfigInt("config_mouseprimary")) { + if (button == App.getConfigInt("control_mouse_primary")) { terrarumIngame.worldPrimaryClickEnd(terrarumIngame.actorNowPlaying!!, App.UPDATE_RATE) } - if (button == App.getConfigInt("config_mousesecondary")) { + if (button == App.getConfigInt("control_mouse_secondary")) { terrarumIngame.worldSecondaryClickEnd(terrarumIngame.actorNowPlaying!!, App.UPDATE_RATE) } // } diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index c96bca310..18f0accd1 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -332,7 +332,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { - if (!Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (!Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_primary"))) { disableMouseClick = false } } @@ -368,7 +368,7 @@ class BuildingMaker(batch: FlippingSpriteBatch) : IngameInstance(batch) { // TODO drag support using bresenham's algo // for some reason it just doesn't work... } - else if (!uiPenMenu.isVisible && Gdx.input.isButtonPressed(App.getConfigInt("config_mousesecondary"))) { + else if (!uiPenMenu.isVisible && Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_secondary"))) { // open pen menu // position the menu to where the cursor is uiPenMenu.posX = Terrarum.mouseScreenX - uiPenMenu.width / 2 diff --git a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt index 90476b118..e3390dd2f 100644 --- a/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt +++ b/src/net/torvald/terrarum/modulebasegame/TitleScreen.kt @@ -513,7 +513,7 @@ class TitleScreen(batch: FlippingSpriteBatch) : IngameInstance(batch) { if (Terrarum.mouseScreenX in tx - 32 until tx + tw + 32 && Terrarum.mouseScreenY in ty2 - 16 until ty2 + App.fontGame.lineHeight.toInt() + 16) { - if (Gdx.input.isButtonJustPressed(App.getConfigInt("config_mouseprimary"))) { + if (Gdx.input.isButtonJustPressed(App.getConfigInt("control_mouse_primary"))) { OpenURL(TerrarumAppConfiguration.FIXED_LATEST_DOWNLOAD_LINK) } batch.color = Toolkit.Theme.COL_SELECTED diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt index f74741dd3..84ed5b9ab 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/BlockBase.kt @@ -153,7 +153,7 @@ object BlockBase { val wirePlaceMode = WireCodex[itemID].branching - if (Gdx.input.isButtonJustPressed(App.getConfigInt("config_mouseprimary")) || + if (Gdx.input.isButtonJustPressed(App.getConfigInt("control_mouse_primary")) || !isNeighbouring(ww, mtx, mty, oldTileX, oldTileY)) { initialMouseDownTileX = mtx initialMouseDownTileY = mty diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemWrench.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemWrench.kt index 9ca5b3a8c..8592d611d 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/ItemWrench.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/ItemWrench.kt @@ -22,8 +22,8 @@ class ItemWrench(originalID: ItemID) : GameItem(originalID), FixtureInteractionB companion object { private val SP = "\u3000" - private val ML = getMouseButton(App.getConfigInt("config_mouseprimary")) - private val MR = getMouseButton(App.getConfigInt("config_mousesecondary")) + private val ML = getMouseButton(App.getConfigInt("control_mouse_primary")) + private val MR = getMouseButton(App.getConfigInt("control_mouse_secondary")) } override val disallowToolDragging = true diff --git a/src/net/torvald/terrarum/modulebasegame/ui/SmelterGuiEventBuilder.kt b/src/net/torvald/terrarum/modulebasegame/ui/SmelterGuiEventBuilder.kt index 67b4865c2..ffd277f05 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/SmelterGuiEventBuilder.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/SmelterGuiEventBuilder.kt @@ -35,9 +35,9 @@ object SmelterGuiEventBuilder { ): (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit { return { gameItem: GameItem?, amount: Long, mouseButton: Int, itemExtraInfo: Any?, theButton: UIItemInventoryCellBase -> val playerInventory = getPlayerInventory() - val amount = if (mouseButton == App.getConfigInt("config_mouseprimary")) + val amount = if (mouseButton == App.getConfigInt("control_mouse_primary")) amount - else if (mouseButton == App.getConfigInt("config_mousesecondary")) + else if (mouseButton == App.getConfigInt("control_mouse_secondary")) 1 else null @@ -175,9 +175,9 @@ object SmelterGuiEventBuilder { itemListUpdate { oreItemFilter(it.itm) } } else if (oreItemStatus.isNotNull()) { - val removeCount = if (mouseButton == App.getConfigInt("config_mouseprimary")) + val removeCount = if (mouseButton == App.getConfigInt("control_mouse_primary")) oreItemStatus.qty - else if (mouseButton == App.getConfigInt("config_mousesecondary")) + else if (mouseButton == App.getConfigInt("control_mouse_secondary")) 1L else null @@ -254,9 +254,9 @@ object SmelterGuiEventBuilder { itemListUpdate { ItemCodex.hasTag(it.itm, "COMBUSTIBLE") } } else if (fireboxItemStatus.isNotNull()) { - val removeCount = if (mouseButton == App.getConfigInt("config_mouseprimary")) + val removeCount = if (mouseButton == App.getConfigInt("control_mouse_primary")) fireboxItemStatus.qty - else if (mouseButton == App.getConfigInt("config_mousesecondary")) + else if (mouseButton == App.getConfigInt("control_mouse_secondary")) 1L else null @@ -333,9 +333,9 @@ object SmelterGuiEventBuilder { } if (productItemStatus.isNotNull()) { - val removeCount = if (mouseButton == App.getConfigInt("config_mouseprimary")) + val removeCount = if (mouseButton == App.getConfigInt("control_mouse_primary")) productItemStatus.qty - else if (mouseButton == App.getConfigInt("config_mousesecondary")) + else if (mouseButton == App.getConfigInt("control_mouse_secondary")) 1L else null diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIAlloyingFurnace.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIAlloyingFurnace.kt index be40d481c..a3c3c9d80 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIAlloyingFurnace.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIAlloyingFurnace.kt @@ -260,8 +260,8 @@ class UIAlloyingFurnace(val smelter: FixtureAlloyingFurnace) : UICanvas( } private val SP = "\u3000" - private val ML = getMouseButton(App.getConfigInt("config_mouseprimary")) - private val MR = getMouseButton(App.getConfigInt("config_mousesecondary")) + private val ML = getMouseButton(App.getConfigInt("control_mouse_primary")) + private val MR = getMouseButton(App.getConfigInt("control_mouse_secondary")) private val MW = getMouseButton(2) private val controlHelpForSmelter = listOf( // no slot selected diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt index 4a6fc589e..d93aebef5 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIItemInventoryItemGrid.kt @@ -150,7 +150,7 @@ open class UIItemInventoryItemGrid( fun createInvCellGenericTouchDownFun(listRebuildFun: () -> Unit): (GameItem?, Long, Int, Any?, UIItemInventoryCellBase) -> Unit { return { item: GameItem?, amount: Long, button: Int, _, _ -> - if (button == App.getConfigInt("config_mouseprimary")) { + if (button == App.getConfigInt("control_mouse_primary")) { if (item != null && Terrarum.ingame != null) { // equip da shit val itemEquipSlot = item.equipPosition diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt index f6f2ff4a8..6b48516a2 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIJukeboxInventory.kt @@ -61,7 +61,7 @@ class UIJukeboxInventory(val parent: UIJukebox) : UICanvas() { init { fixtureDiscCell.forEachIndexed { index, thisButton -> thisButton.touchDownFun = { gameItem, amount, mouseButton, _, _ -> - if (operatedByTheInstaller && mouseButton == App.getConfigInt("config_mouseprimary")) { + if (operatedByTheInstaller && mouseButton == App.getConfigInt("control_mouse_primary")) { if (gameItem != null) { // if the disc being removed is the same disc being played, stop the playback if (index == parent.parent.discCurrentlyPlaying) { @@ -175,7 +175,7 @@ class UIJukeboxSonglistPanel(val parent: UIJukebox) : UICanvas() { colourTheme = songButtonColourTheme, keyDownFun = { _, _, _ -> Unit }, touchDownFun = { index, button, _ -> - if (button == App.getConfigInt("config_mouseprimary") && !parent.parent.musicIsPlaying) { + if (button == App.getConfigInt("control_mouse_primary") && !parent.parent.musicIsPlaying) { parent.parent.playDisc(index) } } diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIKeyboardControlPanel.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIKeyboardControlPanel.kt index 699731982..a5aa0ac89 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIKeyboardControlPanel.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIKeyboardControlPanel.kt @@ -139,7 +139,8 @@ class UIKeyboardControlPanel(remoCon: UIRemoCon?) : UICanvas() { }*/ presetSelector.selectionChangeListener = { index -> - App.setConfig("control_preset_keyboard", ControlPresets.presetLabels[index]) + ControlPresetConfig.set("control_preset_keyboard", ControlPresets.presetLabels[index]) + ControlPresetConfig.save() updateKeycaps() } @@ -163,8 +164,11 @@ class UIKeyboardControlPanel(remoCon: UIRemoCon?) : UICanvas() { "control_key_crafting", "control_key_discard", ).forEach { - App.setConfig(it, DefaultConfig.hashMap[it]!! as Int) + // Reset to ESDF defaults (matches ControlPresetConfig defaults) + val defaultKey = ControlPresets.esdf[it] ?: return@forEach + ControlPresetConfig.set(it, defaultKey) } + ControlPresetConfig.save() } private fun updateKeycaps() { @@ -243,18 +247,19 @@ class UIKeyboardControlPanel(remoCon: UIRemoCon?) : UICanvas() { } fun setControlOf(key: Int, control: Int) { - if (App.getConfigString("control_preset_keyboard") != "Custom") { - System.err.println("[UIKeyboardControlPanel] cannot set a control if the preset is not 'Custom' (current preset: ${App.getConfigString("control_preset_keyboard")})") + if (ControlPresetConfig.getString("control_preset_keyboard") != "Custom") { + System.err.println("[UIKeyboardControlPanel] cannot set a control if the preset is not 'Custom' (current preset: ${ControlPresetConfig.getString("control_preset_keyboard")})") return } if (control >= 0) { val controlName = UIItemControlPaletteBaloon.indexToConfigKey[control]!! - val conflicts = App.gameConfig.keySet.filter { + // Check for conflicts in ControlPresetConfig + val conflicts = ControlPresetConfig.keySet.filter { (it as String).startsWith("control_key_") }.map { (it as String).let { it to - try { (App.getConfigInt(it) == key) } + try { (ControlPresetConfig.getInt(it) == key) } catch (_: ClassCastException) { false } } }.filter { it.second }.map { it.first }.firstOrNull() @@ -262,13 +267,14 @@ class UIKeyboardControlPanel(remoCon: UIRemoCon?) : UICanvas() { println("[UIKeyboardControlPanel] key=$key, control=$controlName") if (conflicts != null) { - val oldValue = App.getConfigInt(controlName) - App.setConfig(conflicts, oldValue) + val oldValue = ControlPresetConfig.getInt(controlName) + ControlPresetConfig.set(conflicts, oldValue) println("[UIKeyboardControlPanel] set config $conflicts=$oldValue") } - App.setConfig(controlName, key) + ControlPresetConfig.set(controlName, key) + ControlPresetConfig.save() println("[UIKeyboardControlPanel] set config $controlName=$key") } updateKeycaps() diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UISmelterBasic.kt b/src/net/torvald/terrarum/modulebasegame/ui/UISmelterBasic.kt index 81597cb4f..4191f9c94 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UISmelterBasic.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UISmelterBasic.kt @@ -246,8 +246,8 @@ class UISmelterBasic(val smelter: FixtureSmelterBasic) : UICanvas( } private val SP = "\u3000" - private val ML = getMouseButton(App.getConfigInt("config_mouseprimary")) - private val MR = getMouseButton(App.getConfigInt("config_mousesecondary")) + private val ML = getMouseButton(App.getConfigInt("control_mouse_primary")) + private val MR = getMouseButton(App.getConfigInt("control_mouse_secondary")) private val MW = getMouseButton(2) private val controlHelpForSmelter = listOf( // no slot selected diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIStorageChest.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIStorageChest.kt index 6b9be9292..ff4a1744f 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIStorageChest.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIStorageChest.kt @@ -97,9 +97,9 @@ internal class UIStorageChest : UICanvas( itemListChest = UITemplateHalfInventory(this, true, { getFixtureInventory() }, { chestNameFun() }).also { it.itemListKeyDownFun = { _, _, _, _, _ -> Unit } it.itemListTouchDownFun = { gameItem, amount, button, _, _ -> - val amount = if (button == App.getConfigInt("config_mouseprimary")) + val amount = if (button == App.getConfigInt("control_mouse_primary")) amount - else if (button == App.getConfigInt("config_mousesecondary")) + else if (button == App.getConfigInt("control_mouse_secondary")) 1 else null @@ -137,9 +137,9 @@ internal class UIStorageChest : UICanvas( itemListPlayer = UITemplateHalfInventory(this, false).also { it.itemListKeyDownFun = { _, _, _, _, _ -> Unit } it.itemListTouchDownFun = { gameItem, amount, button, _, _ -> - val amount = if (button == App.getConfigInt("config_mouseprimary")) + val amount = if (button == App.getConfigInt("control_mouse_primary")) amount - else if (button == App.getConfigInt("config_mousesecondary")) + else if (button == App.getConfigInt("control_mouse_secondary")) 1 else null @@ -227,8 +227,8 @@ internal class UIStorageChest : UICanvas( private val cellsWidth = (UIItemInventoryItemGrid.listGap + UIItemInventoryElemWide.height) * 6 - UIItemInventoryItemGrid.listGap private val SP = "\u3000" - private val ML = getMouseButton(App.getConfigInt("config_mouseprimary")) - private val MR = getMouseButton(App.getConfigInt("config_mousesecondary")) + private val ML = getMouseButton(App.getConfigInt("control_mouse_primary")) + private val MR = getMouseButton(App.getConfigInt("control_mouse_secondary")) private val MW = getMouseButton(2) private val controlHelpLeft: String get() = if (App.environment == RunningEnvironment.PC) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalCargo.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalCargo.kt index d2d5d663a..2b8f896f9 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalCargo.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIWorldPortalCargo.kt @@ -96,7 +96,7 @@ class UIWorldPortalCargo(val full: UIWorldPortal) : UICanvas(), HasInventory { keyDownFun = { _, _, _, _, _ -> Unit }, wheelFun = { _, _, _, _, _, _ -> }, touchDownFun = { gameItem, amount, button, _, _ -> - if (button == App.getConfigInt("config_mouseprimary")) { + if (button == App.getConfigInt("control_mouse_primary")) { if (gameItem != null) { negotiator.refund(getFixtureInventory(), getPlayerInventory(), gameItem, amount) } @@ -119,7 +119,7 @@ class UIWorldPortalCargo(val full: UIWorldPortal) : UICanvas(), HasInventory { keyDownFun = { _, _, _, _, _ -> Unit }, wheelFun = { _, _, _, _, _, _ -> }, touchDownFun = { gameItem, amount, button, _, _ -> - if (button == App.getConfigInt("config_mouseprimary")) { + if (button == App.getConfigInt("control_mouse_primary")) { if (gameItem != null) { negotiator.accept(getPlayerInventory(), getFixtureInventory(), gameItem, amount) } diff --git a/src/net/torvald/terrarum/serialise/WriteConfig.kt b/src/net/torvald/terrarum/serialise/WriteConfig.kt index 5234d4e87..ed3664537 100644 --- a/src/net/torvald/terrarum/serialise/WriteConfig.kt +++ b/src/net/torvald/terrarum/serialise/WriteConfig.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.utils.Json import com.badlogic.gdx.utils.JsonValue import com.badlogic.gdx.utils.JsonWriter import net.torvald.terrarum.App +import net.torvald.terrarum.ControlPresetConfig import net.torvald.terrarum.KVHashMap import net.torvald.terrarum.Principii import net.torvald.terrarum.utils.JsonFetcher @@ -61,9 +62,16 @@ object WriteConfig { }*/ operator fun invoke() { + // Filter out control entries that now live in controls.json + val filteredConfig = KVHashMap() + App.gameConfig.hashMap.forEach { (k, v) -> + if (!ControlPresetConfig.isControlKey(k)) { + filteredConfig[k] = v + } + } + val writer = java.io.FileWriter(App.configDir, false) - //writer.write(getJson()) - writer.write(jsoner.prettyPrint(App.gameConfig)) + writer.write(jsoner.prettyPrint(filteredConfig)) writer.close() } diff --git a/src/net/torvald/terrarum/ui/ConsoleWindow.kt b/src/net/torvald/terrarum/ui/ConsoleWindow.kt index 73cac0989..347764523 100644 --- a/src/net/torvald/terrarum/ui/ConsoleWindow.kt +++ b/src/net/torvald/terrarum/ui/ConsoleWindow.kt @@ -87,7 +87,7 @@ class ConsoleWindow : UICanvas() { releaseTooltip() // click to enter the actor's reference ID - if (lb.size > 0 && !clickLatched && Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (lb.size > 0 && !clickLatched && Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_primary"))) { clickLatched = true textinput.appendText(lb.first().substringBefore(' ')) } @@ -100,7 +100,7 @@ class ConsoleWindow : UICanvas() { uiItems.forEach { it.update(delta) } - if (!Gdx.input.isButtonPressed(App.getConfigInt("config_mouseprimary"))) { + if (!Gdx.input.isButtonPressed(App.getConfigInt("control_mouse_primary"))) { clickLatched = false } diff --git a/src/net/torvald/terrarum/ui/MouseLatch.kt b/src/net/torvald/terrarum/ui/MouseLatch.kt index 64c4ff657..d028cf80e 100644 --- a/src/net/torvald/terrarum/ui/MouseLatch.kt +++ b/src/net/torvald/terrarum/ui/MouseLatch.kt @@ -7,7 +7,7 @@ import java.util.concurrent.atomic.AtomicBoolean /** * Created by minjaesong on 2024-01-10. */ -class MouseLatch(val button: List = listOf(App.getConfigInt("config_mouseprimary"))) { +class MouseLatch(val button: List = listOf(App.getConfigInt("control_mouse_primary"))) { private val status = AtomicBoolean() diff --git a/src/net/torvald/terrarum/ui/UIItem.kt b/src/net/torvald/terrarum/ui/UIItem.kt index 154016336..51a6c44f3 100644 --- a/src/net/torvald/terrarum/ui/UIItem.kt +++ b/src/net/torvald/terrarum/ui/UIItem.kt @@ -249,7 +249,7 @@ abstract class UIItem(var parentUI: UICanvas, val initialX: Int, val initialY: I actionDone = true } - if (!clickOnceListenerFired && mouseUp && button == App.getConfigInt("config_mouseprimary")) { + if (!clickOnceListenerFired && mouseUp && button == App.getConfigInt("control_mouse_primary")) { clickOnceListener.invoke(itemRelativeMouseX, itemRelativeMouseY) if (!suppressHaptic) playHapticPushedDown()