Skip to content

Commit 9e95bac

Browse files
HybridDogsfan5
authored andcommittedSep 26, 2019
Automatically enable depends of mods when enabling the mods in the world config menu (#3473)
1 parent 26b39f1 commit 9e95bac

File tree

1 file changed

+93
-15
lines changed

1 file changed

+93
-15
lines changed
 

‎builtin/mainmenu/pkgmgr.lua

+93-15
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,8 @@ function pkgmgr.identify_modname(modpath,filename)
285285
end
286286
--------------------------------------------------------------------------------
287287
function pkgmgr.render_packagelist(render_list)
288-
if render_list == nil then
289-
if pkgmgr.global_mods == nil then
288+
if not render_list then
289+
if not pkgmgr.global_mods then
290290
pkgmgr.refresh_globals()
291291
end
292292
render_list = pkgmgr.global_mods
@@ -347,35 +347,113 @@ function pkgmgr.is_modpack_entirely_enabled(data, name)
347347
return true
348348
end
349349

350-
---------- toggles or en/disables a mod or modpack -----------------------------
350+
---------- toggles or en/disables a mod or modpack and its dependencies --------
351351
function pkgmgr.enable_mod(this, toset)
352-
local mod = this.data.list:get_list()[this.data.selected_mod]
352+
local list = this.data.list:get_list()
353+
local mod = list[this.data.selected_mod]
353354

354-
-- game mods can't be enabled or disabled
355+
-- Game mods can't be enabled or disabled
355356
if mod.is_game_content then
356357
return
357358
end
358359

359-
-- toggle or en/disable the mod
360+
local toggled_mods = {}
361+
362+
local enabled_mods = {}
360363
if not mod.is_modpack then
364+
-- Toggle or en/disable the mod
361365
if toset == nil then
362-
mod.enabled = not mod.enabled
363-
else
366+
toset = not mod.enabled
367+
end
368+
if mod.enabled ~= toset then
364369
mod.enabled = toset
370+
toggled_mods[#toggled_mods+1] = mod.name
365371
end
372+
if toset then
373+
-- Mark this mod for recursive dependency traversal
374+
enabled_mods[mod.name] = true
375+
end
376+
else
377+
-- Toggle or en/disable every mod in the modpack,
378+
-- interleaved unsupported
379+
for i = 1, #list do
380+
if list[i].modpack == mod.name then
381+
if toset == nil then
382+
toset = not list[i].enabled
383+
end
384+
if list[i].enabled ~= toset then
385+
list[i].enabled = toset
386+
toggled_mods[#toggled_mods+1] = list[i].name
387+
end
388+
if toset then
389+
enabled_mods[list[i].name] = true
390+
end
391+
end
392+
end
393+
end
394+
if not toset then
395+
-- Mod(s) were disabled, so no dependencies need to be enabled
396+
table.sort(toggled_mods)
397+
minetest.log("info", "Following mods were disabled: " ..
398+
table.concat(toggled_mods, ", "))
366399
return
367400
end
368401

369-
-- toggle or en/disable every mod in the modpack, interleaved unsupported
370-
local list = this.data.list:get_raw_list()
371-
for i = 1, #list do
372-
if list[i].modpack == mod.name then
373-
if toset == nil then
374-
toset = not list[i].enabled
402+
-- Enable mods' depends after activation
403+
404+
-- Make a list of mod ids indexed by their names
405+
local mod_ids = {}
406+
for id, mod in pairs(list) do
407+
if mod.type == "mod" and not mod.is_modpack then
408+
mod_ids[mod.name] = id
409+
end
410+
end
411+
412+
-- to_enable is used as a DFS stack with sp as stack pointer
413+
local to_enable = {}
414+
local sp = 0
415+
for name in pairs(enabled_mods) do
416+
local depends = pkgmgr.get_dependencies(list[mod_ids[name]].path)
417+
for i = 1, #depends do
418+
local dependency_name = depends[i]
419+
if not enabled_mods[dependency_name] then
420+
sp = sp+1
421+
to_enable[sp] = dependency_name
375422
end
376-
list[i].enabled = toset
377423
end
378424
end
425+
-- If sp is 0, every dependency is already activated
426+
while sp > 0 do
427+
local name = to_enable[sp]
428+
sp = sp-1
429+
430+
if not enabled_mods[name] then
431+
enabled_mods[name] = true
432+
local mod = list[mod_ids[name]]
433+
if not mod then
434+
minetest.log("warning", "Mod dependency \"" .. name ..
435+
"\" not found!")
436+
else
437+
if mod.enabled == false then
438+
mod.enabled = true
439+
toggled_mods[#toggled_mods+1] = mod.name
440+
end
441+
-- Push the dependencies of the dependency onto the stack
442+
local depends = pkgmgr.get_dependencies(mod.path)
443+
for i = 1, #depends do
444+
if not enabled_mods[name] then
445+
sp = sp+1
446+
to_enable[sp] = depends[i]
447+
end
448+
end
449+
end
450+
end
451+
end
452+
453+
-- Log the list of enabled mods
454+
table.sort(toggled_mods)
455+
minetest.log("info", "Following mods were enabled: " ..
456+
table.concat(toggled_mods, ", "))
379457
end
380458

381459
--------------------------------------------------------------------------------

0 commit comments

Comments
 (0)
Please sign in to comment.