Support using multiple lua init scripts per save.

This should make it easier to add and remove init script code by
automated means, or install multiple mods that need such code.
develop
Alexander Gavrilov 2014-03-31 16:00:55 +04:00
parent f26a943d26
commit a09e132107
4 changed files with 47 additions and 17 deletions

@ -3270,8 +3270,9 @@ The <tt class="docutils literal">name</tt> argument should be the name stem, as
<div class="section" id="save-init-script">
<h2><a class="toc-backref" href="#id62">Save init script</a></h2>
<p>If a save directory contains a file called <tt class="docutils literal">raw/init.lua</tt>, it is
automatically loaded and executed every time the save is loaded. It
can also define the following functions to be called by dfhack:</p>
automatically loaded and executed every time the save is loaded.
The same applies to any files called <tt class="docutils literal"><span class="pre">raw/init.d/*.lua</span></tt>. Every
such script can define the following functions to be called by dfhack:</p>
<ul>
<li><p class="first"><tt class="docutils literal">function onStateChange(op) ... end</tt></p>
<p>Automatically called from the regular onStateChange event as long
@ -3281,7 +3282,8 @@ cleanup concerns.</p>
</li>
<li><p class="first"><tt class="docutils literal">function onUnload() ... end</tt></p>
<p>Called when the save containing the script is unloaded. This function
should clean up any global hooks installed by the script.</p>
should clean up any global hooks installed by the script. Note that
when this is called, the world is already completely unloaded.</p>
</li>
</ul>
<p>Within the init script, the path to the save directory is available as <tt class="docutils literal">SAVE_PATH</tt>.</p>

@ -3199,8 +3199,9 @@ Save init script
================
If a save directory contains a file called ``raw/init.lua``, it is
automatically loaded and executed every time the save is loaded. It
can also define the following functions to be called by dfhack:
automatically loaded and executed every time the save is loaded.
The same applies to any files called ``raw/init.d/*.lua``. Every
such script can define the following functions to be called by dfhack:
* ``function onStateChange(op) ... end``
@ -3212,6 +3213,7 @@ can also define the following functions to be called by dfhack:
* ``function onUnload() ... end``
Called when the save containing the script is unloaded. This function
should clean up any global hooks installed by the script.
should clean up any global hooks installed by the script. Note that
when this is called, the world is already completely unloaded.
Within the init script, the path to the save directory is available as ``SAVE_PATH``.

@ -3,8 +3,11 @@ DFHack future
Internals:
- support for calling a lua function via a protobuf request (demonstrated by dfhack-run --lua).
- Lua API for listing files in directory. Needed for mod-manager.
- support for multiple raw/init.d/*.lua init scripts in one save.
New scripts:
- gui/mod-manager: allows installing/uninstalling mods into df from df/mods directory.
- gui/clone-uniform: duplicates the currently selected uniform in the military screen.
New commands:
- move the 'grow', 'extirpate' and 'immolate' commands as 'plant' subcommands

@ -366,11 +366,28 @@ function dfhack.getSavePath()
end
if dfhack.is_core_context then
local function loadInitFile(path, name)
local env = setmetatable({ SAVE_PATH = path }, { __index = base_env })
local f,perr = loadfile(name, 't', env)
if f == nil then
if not string.match(perr, 'No such file or directory') then
dfhack.printerr(perr)
end
elseif safecall(f) then
if not internal.save_init then
internal.save_init = {}
end
table.insert(internal.save_init, env)
end
end
dfhack.onStateChange.DFHACK_PER_SAVE = function(op)
if op == SC_WORLD_LOADED or op == SC_WORLD_UNLOADED then
if internal.save_init then
if internal.save_init.onUnload then
safecall(internal.save_init.onUnload)
for k,v in ipairs(internal.save_init) do
if v.onUnload then
safecall(v.onUnload)
end
end
internal.save_init = nil
end
@ -378,18 +395,24 @@ if dfhack.is_core_context then
local path = dfhack.getSavePath()
if path and op == SC_WORLD_LOADED then
local env = setmetatable({ SAVE_PATH = path }, { __index = base_env })
local f,perr = loadfile(path..'/raw/init.lua', 't', env)
if f == nil then
if not string.match(perr, 'No such file or directory') then
dfhack.printerr(perr)
loadInitFile(path, path..'/raw/init.lua')
local dirlist = dfhack.internal.getDir(path..'/raw/init.d/')
if dirlist then
table.sort(dirlist)
for i,name in ipairs(dirlist) do
if string.match(name,'%.lua$') then
loadInitFile(path, path..'/raw/init.d/'..name)
end
end
elseif safecall(f) then
internal.save_init = env
end
end
elseif internal.save_init and internal.save_init.onStateChange then
safecall(internal.save_init.onStateChange, op)
elseif internal.save_init then
for k,v in ipairs(internal.save_init) do
if v.onStateChange then
safecall(v.onStateChange, op)
end
end
end
end
end