Allow Lua scripts to be used as modules.

develop
expwnent 2015-01-31 22:43:54 -05:00
parent 92bd6349a7
commit bf5e491647
4 changed files with 26 additions and 3 deletions

@ -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. 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 Save init script
================ ================

@ -1,6 +1,7 @@
DFHack Future DFHack Future
Internals Internals
Lua scripts can set environment variables of each other with dfhack.run_script_with_env. 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 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) Filesystem module now provides file access/modification times and can list directories (normally and recursively)
Units Module: New functions: Units Module: New functions:

@ -385,7 +385,7 @@ internal.scripts = internal.scripts or {}
local scripts = internal.scripts local scripts = internal.scripts
local hack_path = dfhack.getHackPath() local hack_path = dfhack.getHackPath()
local function findScript(name) function dfhack.findScript(name)
local file local file
file = dfhack.getSavePath() file = dfhack.getSavePath()
if file then if file then
@ -410,8 +410,13 @@ function dfhack.run_script(name,...)
return dfhack.run_script_with_env(nil,name,...) return dfhack.run_script_with_env(nil,name,...)
end 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,...) function dfhack.run_script_with_env(envVars,name,...)
local file = findScript(name) local file = dfhack.findScript(name)
if not file then if not file then
error('Could not find script ' .. name) error('Could not find script ' .. name)
end end

@ -2,7 +2,7 @@
local utils=require('utils') 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 local emotions=unit.status.current_soul.personality.emotions
if not (type(emotion)=='number') then emotion=df.emotion_type[emotion] end 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 if not (type(thought)=='number') then thought=df.unit_thought_type[thought] end
@ -41,6 +41,10 @@ function tablify(iterableObject)
return t return t
end end
if moduleMode then
return
end
local args = utils.processArgs({...}, validArgs) local args = utils.processArgs({...}, validArgs)
local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true) local unit = args.unit and df.unit.find(args.unit) or dfhack.gui.getSelectedUnit(true)