diff --git a/docs/Core.rst b/docs/Core.rst index c17d3fdb31..54fa737710 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -375,9 +375,10 @@ on UNIX-like systems: with the default, if this port cannot be used, the server is not started. See `remote` for more details. -- ``DFHACK_DISABLE_CONSOLE``: if set, the DFHack console is not set up. This is - the default behavior if ``PRINT_MODE:TEXT`` is set in ``data/init/init.txt``. - Intended for situations where DFHack cannot run in a terminal window. +- ``DFHACK_DISABLE_CONSOLE``: if set, DFHack's external console is not set up. + This is the default behavior if ``PRINT_MODE:TEXT`` is set in + ``data/init/init.txt``. Intended for situations where DFHack cannot run in a + terminal window. - ``DFHACK_HEADLESS``: if set, and ``PRINT_MODE:TEXT`` is set, DF's display will be hidden, and the console will be started unless ``DFHACK_DISABLE_CONSOLE`` @@ -409,19 +410,23 @@ Other (non-DFHack-specific) variables that affect DFHack: Core preferences ================ -There are a few settings that can be changed dynamically via -`gui/control-panel` to affect runtime behavior. You can also toggle these from -the commandline using the `lua` command, e.g. -``lua dfhack.HIDE_ARMOK_TOOLS=true`` or by editing the generated -``dfhack-config/init/dfhack.control-panel-preferences.init`` file and -restarting DF. - -- ``dfhack.HIDE_CONSOLE_ON_STARTUP``: Whether to hide the external DFHack - terminal window on startup. This, of course, is not useful to change - dynamically. You'll have to use `gui/control-panel` or edit the init file - directly and restart DF for it to have an effect. - -- ``dfhack.HIDE_ARMOK_TOOLS``: Whether to hide "armok" tools in command lists. +Settings that control DFHack's runtime behavior can be changed dynamically via +the "Preferences" tab in `gui/control-panel` or on the commandline with +`control-panel`. The two most important settings for the core are: + +- ``HIDE_CONSOLE_ON_STARTUP``: On Windows, this controls whether to hide the + external DFHack terminal window on startup. The console is hidden by default + so it does not get in the way of gameplay, but it can be useful to enable for + debugging purposes or if you just prefer to use the external console instead + of the in-game `gui/launcher`. When you change this setting, the new behavior + will take effect the next time you start the game. If you are running the + native Linux version of DF (and DFHack), the terminal that you run the game + from becomes the DFHack console and this setting has no effect. + +- ``HIDE_ARMOK_TOOLS``: Whether to hide "armok" tools in command lists. Also + known as "Mortal mode", this setting keeps god-mode tools out of sight and + out of mind. Highly recommended for players who would prefer if the god-mode + tools were not quite as obvious and accessible. Performance monitoring ====================== diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index da48cedf61..2449135e15 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -3205,6 +3205,12 @@ and are only documented here for completeness: Gets and sets the flag for whether to suppress DF key events when a DFHack keybinding is matched and a command is launched. +* ``dfhack.internal.setMortalMode(value)`` +* ``dfhack.internal.setArmokTools(tool_names)`` + + Used to sync mortal mode state to DFHack Core memory for use in keybinding + checks. + .. _lua-core-context: Core interpreter context diff --git a/library/Core.cpp b/library/Core.cpp index 4e17d93986..3241ed0516 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -2381,6 +2381,15 @@ void Core::setSuppressDuplicateKeyboardEvents(bool suppress) { suppress_duplicate_keyboard_events = suppress; } +void Core::setMortalMode(bool value) { + mortal_mode = value; +} + +void Core::setArmokTools(const std::vector &tool_names) { + armok_tools.clear(); + armok_tools.insert(tool_names.begin(), tool_names.end()); +} + // returns true if the event is handled bool Core::DFH_SDL_Event(SDL_Event* ev) { uint32_t start_ms = p->getTickCount(); @@ -2460,23 +2469,6 @@ bool Core::doSdlInputEvent(SDL_Event* ev) return false; } -static bool should_hide_from_mortals(const std::string &command) { - auto &out = Core::getInstance().getConsole(); - - bool is_mortal = false; - Lua::CallLuaModuleFunction(out, "dfhack", "getHideArmokTools", {}, 1, - [&](lua_State* L) { is_mortal = lua_toboolean(L, -1); }); - - if (!is_mortal) - return false; - - bool is_armok = false; - Lua::CallLuaModuleFunction(out, "helpdb", "has_tag", std::make_tuple(command, "armok"), 1, - [&](lua_State* L) { is_armok = lua_toboolean(L, -1); }); - - return is_armok; -} - bool Core::SelectHotkey(int sym, int modifiers) { // Find the topmost viewscreen @@ -2521,7 +2513,7 @@ bool Core::SelectHotkey(int sym, int modifiers) binding.command[0].c_str()); continue; } - if (should_hide_from_mortals(binding.command[0])) { + if (mortal_mode && armok_tools.contains(binding.command[0])) { DEBUG(keybinding).print("skipping keybinding due to mortal mode (command: '%s')\n", binding.command[0].c_str()); continue; diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 0119a0405a..99d2edf216 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -4002,6 +4002,19 @@ static int internal_setSuppressDuplicateKeyboardEvents(lua_State *L) { return 0; } +static int internal_setMortalMode(lua_State *L) { + bool value = lua_toboolean(L, 1); + Core::getInstance().setMortalMode(value); + return 0; +} + +static int internal_setArmokTools(lua_State *L) { + std::vector tool_names; + Lua::GetVector(L, tool_names); + Core::getInstance().setArmokTools(tool_names); + return 0; +} + template static std::map translate_event_types(const std::unordered_map & in_map) { std::map out_map; @@ -4096,6 +4109,8 @@ static const luaL_Reg dfhack_internal_funcs[] = { { "md5File", internal_md5file }, { "getSuppressDuplicateKeyboardEvents", internal_getSuppressDuplicateKeyboardEvents }, { "setSuppressDuplicateKeyboardEvents", internal_setSuppressDuplicateKeyboardEvents }, + { "setMortalMode", internal_setMortalMode }, + { "setArmokTools", internal_setArmokTools }, { "getPerfCounters", internal_getPerfCounters }, { NULL, NULL } }; diff --git a/library/include/Core.h b/library/include/Core.h index 2a8d4e3748..642c649d63 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -40,6 +40,7 @@ distribution. #include #include #include +#include #include #include @@ -192,6 +193,8 @@ namespace DFHack bool getSuppressDuplicateKeyboardEvents(); void setSuppressDuplicateKeyboardEvents(bool suppress); + void setMortalMode(bool value); + void setArmokTools(const std::vector &tool_names); bool ClearKeyBindings(std::string keyspec); bool AddKeyBinding(std::string keyspec, std::string cmdline); @@ -285,6 +288,8 @@ namespace DFHack int8_t modstate; bool suppress_duplicate_keyboard_events; + bool mortal_mode; + std::unordered_set armok_tools; std::map > key_bindings; std::string hotkey_cmd; enum hotkey_set_t { diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua index 0c1bc7dc15..d47998e200 100644 --- a/library/lua/dfhack.lua +++ b/library/lua/dfhack.lua @@ -99,13 +99,20 @@ dfhack.HIDE_CONSOLE_ON_STARTUP = true function dfhack.getHideConsoleOnStartup() return dfhack.HIDE_CONSOLE_ON_STARTUP end +function dfhack.setHideConsoleOnStartup(value) + dfhack.HIDE_CONSOLE_ON_STARTUP = value +end dfhack.HIDE_ARMOK_TOOLS = false ---@nodiscard ---@return boolean -function dfhack.getHideArmokTools() +function dfhack.getMortalMode() return dfhack.HIDE_ARMOK_TOOLS end +function dfhack.setMortalMode(value) + dfhack.HIDE_ARMOK_TOOLS = value + dfhack.internal.setMortalMode(value) +end -- Error handling diff --git a/library/lua/helpdb.lua b/library/lua/helpdb.lua index 216f6c582c..0bd64d29cc 100644 --- a/library/lua/helpdb.lua +++ b/library/lua/helpdb.lua @@ -419,6 +419,9 @@ local function ensure_db() scan_plugins(old_db) scan_scripts(old_db) index_tags() + if is_tag('armok') then + dfhack.internal.setArmokTools(get_tag_data('armok')) + end end function refresh() @@ -795,7 +798,7 @@ function ls(filter_str, skip_tags, show_dev_commands, exclude_strs) end if not show_dev_commands then local dev_tags = {'dev', 'unavailable'} - if filter_str ~= 'armok' and dfhack.getHideArmokTools() then + if filter_str ~= 'armok' and dfhack.getMortalMode() then table.insert(dev_tags, 'armok') end table.insert(excludes, {tag=dev_tags}) @@ -828,7 +831,7 @@ function tags(tag) if tag ~= 'unavailable' then table.insert(excludes.tag, 'unavailable') end - if tag ~= 'armok' and dfhack.getHideArmokTools() then + if tag ~= 'armok' and dfhack.getMortalMode() then table.insert(excludes.tag, 'armok') end diff --git a/plugins/lua/hotkeys.lua b/plugins/lua/hotkeys.lua index 23ff25bdbb..b568652d46 100644 --- a/plugins/lua/hotkeys.lua +++ b/plugins/lua/hotkeys.lua @@ -16,7 +16,7 @@ end function should_hide_armok(cmdline) local command = get_command(cmdline) - return dfhack.getHideArmokTools() and helpdb.has_tag(command, 'armok') + return dfhack.getMortalMode() and helpdb.has_tag(command, 'armok') end -- ----------------- --