Merge pull request #3586 from myk002/myk_mod_libraries

infrastructure for mod-added file libraries
develop
Myk 2023-07-21 14:19:37 -07:00 committed by GitHub
commit 993132a334
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 24 deletions

@ -45,6 +45,7 @@ this::
info.txt info.txt
graphics/... graphics/...
objects/... objects/...
blueprints/...
scripts_modactive/example-mod.lua scripts_modactive/example-mod.lua
scripts_modactive/internal/example-mod/... scripts_modactive/internal/example-mod/...
scripts_modinstalled/... scripts_modinstalled/...
@ -58,6 +59,9 @@ Let's go through that line by line.
- Modifications to the game raws (potentially with custom raw tokens) go in - Modifications to the game raws (potentially with custom raw tokens) go in
the :file:`graphics/` and :file:`objects/` folders. You can read more about the :file:`graphics/` and :file:`objects/` folders. You can read more about
the files that go in these directories on the :wiki:`Modding` wiki page. the files that go in these directories on the :wiki:`Modding` wiki page.
- Any `quickfort` blueprints included with your mod go in the
:file:`blueprints` folder. Note that your mod can *just* be blueprints and
nothing else if you like.
- A control script in :file:`scripts_modactive/` directory that handles - A control script in :file:`scripts_modactive/` directory that handles
system-level event hooks (e.g. reloading state when a world is loaded), system-level event hooks (e.g. reloading state when a world is loaded),
registering `overlays <overlay-dev-guide>`, and registering `overlays <overlay-dev-guide>`, and

@ -74,7 +74,7 @@ function list()
end end
--------------------- ---------------------
-- mod script paths -- mod paths
-- this perhaps could/should be queried from the Steam API -- this perhaps could/should be queried from the Steam API
-- are there any installation configurations where this will be wrong, though? -- are there any installation configurations where this will be wrong, though?
@ -98,8 +98,8 @@ local function get_mod_id_and_version(path)
end end
if not version then if not version then
-- note this doesn't include the closing brace since some people put -- note this doesn't include the closing brace since some people put
-- non-number characters in here, and DF only reads the digits as the -- non-number characters in here, and DF only reads the leading digits
-- numeric version -- as the numeric version
_,_,version = line:find('^%[NUMERIC_VERSION:(%d+)') _,_,version = line:find('^%[NUMERIC_VERSION:(%d+)')
end end
-- note that we do *not* want to break out of this loop early since -- note that we do *not* want to break out of this loop early since
@ -108,37 +108,31 @@ local function get_mod_id_and_version(path)
return id, version return id, version
end end
local function add_script_path(mod_script_paths, path) local function add_mod_paths(mod_paths, id, base_path, subdir)
local sep = base_path:endswith('/') and '' or '/'
local path = ('%s%s%s'):format(base_path, sep, subdir)
if dfhack.filesystem.isdir(path) then if dfhack.filesystem.isdir(path) then
print('indexing mod scripts: ' .. path) print('indexing mod path: ' .. path)
table.insert(mod_script_paths, path) table.insert(mod_paths, {id=id, path=path})
end end
end end
local function add_script_paths(mod_script_paths, base_path, include_modactive) function get_mod_paths(installed_subdir, active_subdir)
if not base_path:endswith('/') then
base_path = base_path .. '/'
end
if include_modactive then
add_script_path(mod_script_paths, base_path..'scripts_modactive')
end
add_script_path(mod_script_paths, base_path..'scripts_modinstalled')
end
function get_mod_script_paths()
-- ordered map of mod id -> {handled=bool, versions=map of version -> path} -- ordered map of mod id -> {handled=bool, versions=map of version -> path}
local mods = utils.OrderedTable() local mods = utils.OrderedTable()
local mod_script_paths = {} local mod_paths = {}
-- if a world is loaded, process active mods first, and lock to active version -- if a world is loaded, process active mods first, and lock to active version
if dfhack.isWorldLoaded() then if active_subdir and dfhack.isWorldLoaded() then
for _,path in ipairs(df.global.world.object_loader.object_load_order_src_dir) do for _,path in ipairs(df.global.world.object_loader.object_load_order_src_dir) do
path = tostring(path.value) path = tostring(path.value)
-- skip vanilla "mods"
if not path:startswith(INSTALLED_MODS_PATH) then goto continue end if not path:startswith(INSTALLED_MODS_PATH) then goto continue end
local id = get_mod_id_and_version(path) local id = get_mod_id_and_version(path)
if not id then goto continue end if not id then goto continue end
mods[id] = {handled=true} mods[id] = {handled=true}
add_script_paths(mod_script_paths, path, true) add_mod_paths(mod_paths, id, path, active_subdir)
add_mod_paths(mod_paths, id, path, installed_subdir)
::continue:: ::continue::
end end
end end
@ -159,8 +153,8 @@ function get_mod_script_paths()
::skip_path_root:: ::skip_path_root::
end end
-- add script paths from most recent version of all not-yet-handled mods -- add paths from most recent version of all not-yet-handled mods
for _,v in pairs(mods) do for id,v in pairs(mods) do
if v.handled then goto continue end if v.handled then goto continue end
local max_version, path local max_version, path
for version,mod_path in pairs(v.versions) do for version,mod_path in pairs(v.versions) do
@ -169,11 +163,19 @@ function get_mod_script_paths()
max_version = version max_version = version
end end
end end
add_script_paths(mod_script_paths, path) add_mod_paths(mod_paths, id, path, installed_subdir)
::continue:: ::continue::
end end
return mod_script_paths return mod_paths
end
function get_mod_script_paths()
local paths = {}
for _,v in ipairs(get_mod_paths('scripts_modinstalled', 'scripts_modactive')) do
table.insert(paths, v.path)
end
return paths
end end
return _ENV return _ENV