diff --git a/Lua API.rst b/Lua API.rst index fb94d25cd..9c6aa140c 100644 --- a/Lua API.rst +++ b/Lua API.rst @@ -3399,6 +3399,19 @@ from other scripts) in any context, via the same function the core uses: Note that this function lets errors propagate to the caller. +* ``dfhack.script_environment(name)`` + + Run an Lua script and return its environment. + This command allows you to use scripts like modules for increased portability. + It is highly recommended that if you are a modder you put your custom modules in ``raw/scripts`` and use ``script_environment`` instead of ``require`` so that saves with your mod installed will be self-contained and can be transferred to people who do have DFHack but do not have your mod installed. + You can say ``dfhack.script_environment('add-thought').addEmotionToUnit([arguments go here])`` and it will have the desired effect. + It will call the script in question with the global ``moduleMode`` set to ``true`` so that the script can return early. + This is useful because if the script is called from the console it should deal with its console arguments and if it is called by ``script_environment`` it should only create its global functions and return. + You can also access global variables with, for example ``print(dfhack.script_environment('add-thought').validArgs)`` + The function ``script_environment`` is fast enough that it is recommended that you not store its result in a nonlocal variable, because your script might need to load a different version of that script if the save is unloaded and a save with a different mod that overrides the same script with a slightly different functionality is loaded. + This will not be an issue in most cases. + This function also permits circular dependencies of scripts. + Save init script ================ diff --git a/NEWS b/NEWS index 38e307bc4..515b8fca1 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ DFHack Future Internals Lua scripts can set environment variables of each other with dfhack.run_script_with_env. + Lua scripts can now call each others internal nonlocal functions with dfhack.script_environment(scriptName).functionName(arg1,arg2). eventful Lua reactions no longer require LUA_HOOK as a prefix: you can register a callback for the completion of any reaction with a name Filesystem module now provides file access/modification times and can list directories (normally and recursively) Units Module: New functions: diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua index 9530086c4..37cb4637e 100644 --- a/library/lua/dfhack.lua +++ b/library/lua/dfhack.lua @@ -385,7 +385,7 @@ internal.scripts = internal.scripts or {} local scripts = internal.scripts local hack_path = dfhack.getHackPath() -local function findScript(name) +function dfhack.findScript(name) local file file = dfhack.getSavePath() if file then @@ -410,8 +410,13 @@ function dfhack.run_script(name,...) return dfhack.run_script_with_env(nil,name,...) end +function dfhack.script_environment(name) + _, env = dfhack.run_script_with_env({moduleMode=true}, name) + return env +end + function dfhack.run_script_with_env(envVars,name,...) - local file = findScript(name) + local file = dfhack.findScript(name) if not file then error('Could not find script ' .. name) end diff --git a/scripts/add-thought.lua b/scripts/add-thought.lua index 454782212..2bd648edd 100644 --- a/scripts/add-thought.lua +++ b/scripts/add-thought.lua @@ -2,7 +2,7 @@ local utils=require('utils') -local function addEmotionToUnit(unit,thought,emotion,severity,strength,subthought) +function addEmotionToUnit(unit,thought,emotion,severity,strength,subthought) local emotions=unit.status.current_soul.personality.emotions if not (type(emotion)=='number') then emotion=df.emotion_type[emotion] end if not (type(thought)=='number') then thought=df.unit_thought_type[thought] end @@ -41,6 +41,10 @@ function tablify(iterableObject) return t end +if moduleMode then + return +end + local args = utils.processArgs({...}, validArgs) local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)