Automatically enable depends of mods when enabling the mods in the world config menu...
authorHybridDog <3192173+HybridDog@users.noreply.github.com>
Thu, 26 Sep 2019 19:03:54 +0000 (21:03 +0200)
committersfan5 <sfan5@live.de>
Thu, 26 Sep 2019 19:03:54 +0000 (21:03 +0200)
builtin/mainmenu/pkgmgr.lua

index b9b61296305197f2da640b93cda3e2df4591ea42..f8736768988a5fad51099a4c64ca8e92af395db0 100644 (file)
@@ -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
 
 --------------------------------------------------------------------------------