aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHybridDog <3192173+HybridDog@users.noreply.github.com>2019-09-26 21:03:54 +0200
committersfan5 <sfan5@live.de>2019-09-26 21:03:54 +0200
commit9e95bac75d43534614d168614624fa24048faf48 (patch)
tree7ebc052fc774579aabf93f9519da6bca23a7010e
parent26b39f1eae1f576669cbf49c6db94ef4ed8624df (diff)
downloadminetest-9e95bac75d43534614d168614624fa24048faf48.tar.gz
minetest-9e95bac75d43534614d168614624fa24048faf48.tar.bz2
minetest-9e95bac75d43534614d168614624fa24048faf48.zip
Automatically enable depends of mods when enabling the mods in the world config menu (#3473)
-rw-r--r--builtin/mainmenu/pkgmgr.lua108
1 files changed, 93 insertions, 15 deletions
diff --git a/builtin/mainmenu/pkgmgr.lua b/builtin/mainmenu/pkgmgr.lua
index b9b612963..f87367689 100644
--- a/builtin/mainmenu/pkgmgr.lua
+++ b/builtin/mainmenu/pkgmgr.lua
@@ -285,8 +285,8 @@ function pkgmgr.identify_modname(modpath,filename)
end
--------------------------------------------------------------------------------
function pkgmgr.render_packagelist(render_list)
- if render_list == nil then
- if pkgmgr.global_mods == nil then
+ if not render_list then
+ if not pkgmgr.global_mods then
pkgmgr.refresh_globals()
end
render_list = pkgmgr.global_mods
@@ -347,35 +347,113 @@ function pkgmgr.is_modpack_entirely_enabled(data, name)
return true
end
----------- toggles or en/disables a mod or modpack -----------------------------
+---------- toggles or en/disables a mod or modpack and its dependencies --------
function pkgmgr.enable_mod(this, toset)
- local mod = this.data.list:get_list()[this.data.selected_mod]
+ local list = this.data.list:get_list()
+ local mod = list[this.data.selected_mod]
- -- game mods can't be enabled or disabled
+ -- Game mods can't be enabled or disabled
if mod.is_game_content then
return
end
- -- toggle or en/disable the mod
+ local toggled_mods = {}
+
+ local enabled_mods = {}
if not mod.is_modpack then
+ -- Toggle or en/disable the mod
if toset == nil then
- mod.enabled = not mod.enabled
- else
+ toset = not mod.enabled
+ end
+ if mod.enabled ~= toset then
mod.enabled = toset
+ toggled_mods[#toggled_mods+1] = mod.name
end
+ if toset then
+ -- Mark this mod for recursive dependency traversal
+ enabled_mods[mod.name] = true
+ end
+ else
+ -- Toggle or en/disable every mod in the modpack,
+ -- interleaved unsupported
+ for i = 1, #list do
+ if list[i].modpack == mod.name then
+ if toset == nil then
+ toset = not list[i].enabled
+ end
+ if list[i].enabled ~= toset then
+ list[i].enabled = toset
+ toggled_mods[#toggled_mods+1] = list[i].name
+ end
+ if toset then
+ enabled_mods[list[i].name] = true
+ end
+ end
+ end
+ end
+ if not toset then
+ -- Mod(s) were disabled, so no dependencies need to be enabled
+ table.sort(toggled_mods)
+ minetest.log("info", "Following mods were disabled: " ..
+ table.concat(toggled_mods, ", "))
return
end
- -- toggle or en/disable every mod in the modpack, interleaved unsupported
- local list = this.data.list:get_raw_list()
- for i = 1, #list do
- if list[i].modpack == mod.name then
- if toset == nil then
- toset = not list[i].enabled
+ -- Enable mods' depends after activation
+
+ -- Make a list of mod ids indexed by their names
+ local mod_ids = {}
+ for id, mod in pairs(list) do
+ if mod.type == "mod" and not mod.is_modpack then
+ mod_ids[mod.name] = id
+ end
+ end
+
+ -- to_enable is used as a DFS stack with sp as stack pointer
+ local to_enable = {}
+ local sp = 0
+ for name in pairs(enabled_mods) do
+ local depends = pkgmgr.get_dependencies(list[mod_ids[name]].path)
+ for i = 1, #depends do
+ local dependency_name = depends[i]
+ if not enabled_mods[dependency_name] then
+ sp = sp+1
+ to_enable[sp] = dependency_name
end
- list[i].enabled = toset
end
end
+ -- If sp is 0, every dependency is already activated
+ while sp > 0 do
+ local name = to_enable[sp]
+ sp = sp-1
+
+ if not enabled_mods[name] then
+ enabled_mods[name] = true
+ local mod = list[mod_ids[name]]
+ if not mod then
+ minetest.log("warning", "Mod dependency \"" .. name ..
+ "\" not found!")
+ else
+ if mod.enabled == false then
+ mod.enabled = true
+ toggled_mods[#toggled_mods+1] = mod.name
+ end
+ -- Push the dependencies of the dependency onto the stack
+ local depends = pkgmgr.get_dependencies(mod.path)
+ for i = 1, #depends do
+ if not enabled_mods[name] then
+ sp = sp+1
+ to_enable[sp] = depends[i]
+ end
+ end
+ end
+ end
+ end
+
+ -- Log the list of enabled mods
+ table.sort(toggled_mods)
+ minetest.log("info", "Following mods were enabled: " ..
+ table.concat(toggled_mods, ", "))
end
--------------------------------------------------------------------------------