From 14427725ae8869d5e4b2d8942f7ecf230a87b752 Mon Sep 17 00:00:00 2001 From: cx384 Date: Sat, 3 Jan 2026 15:48:13 +0100 Subject: [PATCH] Select Mods: Show world mods (#16799) --- builtin/mainmenu/content/pkgmgr.lua | 76 +++++++++++++++++---------- builtin/mainmenu/dlg_config_world.lua | 53 +++++++------------ 2 files changed, 68 insertions(+), 61 deletions(-) diff --git a/builtin/mainmenu/content/pkgmgr.lua b/builtin/mainmenu/content/pkgmgr.lua index 38f0d16096..7b8a796b2d 100644 --- a/builtin/mainmenu/content/pkgmgr.lua +++ b/builtin/mainmenu/content/pkgmgr.lua @@ -294,15 +294,16 @@ function pkgmgr.render_packagelist(render_list, use_technical_names, with_icon) end end end - elseif v.is_game_content or v.type == "game" then + elseif v.always_on then icon = 1 color = mt_color_blue - local rawlist = render_list:get_raw_list() - if v.type == "game" and with_icon then - for j = 1, #rawlist do - if rawlist[j].is_game_content then - update_icon_info(with_icon[rawlist[j].virtual_path or rawlist[j].path]) + -- Parent icon depends on contained mods + if v.type == "game" or v.type == "worldmods" then + local rawlist = render_list:get_raw_list() + for _, mod in ipairs(rawlist) do + if v.type == mod.loc then + update_icon_info(with_icon[mod.virtual_path or mod.path]) end end end @@ -327,7 +328,8 @@ function pkgmgr.render_packagelist(render_list, use_technical_names, with_icon) retval[#retval + 1] = color -- `v.modpack_depth` is `nil` for the selected game (treated as level 0) - retval[#retval + 1] = (v.modpack_depth or 0) + (v.loc == "game" and 1 or 0) + retval[#retval + 1] = (v.modpack_depth or 0) + + ((v.loc == "game" or v.loc == "worldmods") and 1 or 0) if with_icon then retval[#retval + 1] = icon @@ -400,8 +402,7 @@ function pkgmgr.enable_mod(this, toset) local list = this.data.list:get_list() local mod = list[this.data.selected_mod] - -- Game mods can't be enabled or disabled - if mod.is_game_content then + if mod.always_on then return end @@ -457,7 +458,7 @@ function pkgmgr.enable_mod(this, toset) if not mod_to_enable then core.log("warning", "Mod dependency \"" .. name .. "\" not found!") - elseif not mod_to_enable.is_game_content then + elseif not mod_to_enable.always_on then if not mod_to_enable.enabled then mod_to_enable.enabled = true toggled_mods[#toggled_mods+1] = mod_to_enable.name @@ -586,23 +587,22 @@ end function pkgmgr.preparemodlist(data) local retval = {} + -- read global mods local global_mods = {} - local game_mods = {} - - --read global mods local modpaths = core.get_modpaths() for key, modpath in pairs(modpaths) do pkgmgr.get_mods(modpath, key, global_mods) end - for i=1,#global_mods,1 do - global_mods[i].type = "mod" - global_mods[i].loc = "global" - global_mods[i].enabled = false - retval[#retval + 1] = global_mods[i] + for _, mod in ipairs(global_mods) do + mod.type = "mod" + mod.loc = "global" + mod.enabled = false + retval[#retval + 1] = mod end - --read game mods + -- read game mods + local game_mods = {} local gamespec = pkgmgr.find_by_gameid(data.gameid) pkgmgr.get_game_mods(gamespec, game_mods) @@ -610,24 +610,46 @@ function pkgmgr.preparemodlist(data) -- Add title retval[#retval + 1] = { type = "game", - is_game_content = true, + always_on = true, name = fgettext("$1 mods", gamespec.title), path = gamespec.path } - end - for i=1,#game_mods,1 do - game_mods[i].type = "mod" - game_mods[i].loc = "game" - game_mods[i].is_game_content = true - retval[#retval + 1] = game_mods[i] + for _, mod in ipairs(game_mods) do + mod.type = "mod" + mod.loc = "game" + mod.always_on = true + retval[#retval + 1] = mod + end end if data.worldpath == nil then return retval end - --read world mod configuration + -- read world mods + local world_mods = {} + local world_mods_path = data.worldpath .. DIR_DELIM .. "worldmods" + pkgmgr.get_mods(world_mods_path, "worldmods", world_mods) + + if #world_mods > 0 then + -- Add title + retval[#retval + 1] = { + type = "worldmods", + always_on = true, + name = fgettext("World mods"), + path = world_mods_path + } + + for _, mod in ipairs(world_mods) do + mod.type = "mod" + mod.loc = "worldmods" + mod.always_on = true + retval[#retval + 1] = mod + end + end + + -- read world mod configuration local filename = data.worldpath .. DIR_DELIM .. "world.mt" diff --git a/builtin/mainmenu/dlg_config_world.lua b/builtin/mainmenu/dlg_config_world.lua index 7cf651317f..60cc6a3c56 100644 --- a/builtin/mainmenu/dlg_config_world.lua +++ b/builtin/mainmenu/dlg_config_world.lua @@ -19,31 +19,17 @@ local function init_data(data) return true end end, - function(element, criteria) - if criteria.hide_game and - element.is_game_content then - return false - end - - if criteria.hide_modpackcontents and - element.modpack ~= nil then - return false - end - return true - end, + nil, { worldpath = data.worldspec.path, gameid = data.worldspec.gameid - }) + } + ) if data.selected_mod > data.list:size() then data.selected_mod = 0 end - data.list:set_filtercriteria({ - hide_game = data.hide_gamemods, - hide_modpackcontents = data.hide_modpackcontents - }) -- Sorting is already done by pgkmgr.get_mods end @@ -127,11 +113,15 @@ local function get_formspec(data) end retval = retval .. "textarea[0.25,0.7;5.75,7.2;;" .. info .. ";]" + elseif mod.type == "worldmods" then + retval = retval .. + "textarea[0.25,0.7;5.75,7.2;;" .. + fgettext("Mods located inside the world folder.") .. ";]" else local hard_deps, soft_deps = pkgmgr.get_dependencies(mod.path) -- Add error messages to dep lists - if mod.enabled or mod.is_game_content then + if mod.enabled or mod.always_on then for i, dep_name in ipairs(hard_deps) do local dep = enabled_mods_by_name[dep_name] if not dep then @@ -201,7 +191,7 @@ local function get_formspec(data) "button[9,7;2.5,0.5;btn_config_world_cdb;" .. fgettext("Find More Mods") .. "]" - if mod.name ~= "" and not mod.is_game_content then + if mod.name ~= "" and not mod.always_on then if mod.is_modpack then if pkgmgr.is_modpack_entirely_enabled(data.list:get_raw_list(), mod) then retval = retval .. @@ -279,8 +269,7 @@ local function handle_buttons(this, fields) for i = 1, #rawlist do local mod = rawlist[i] - if not mod.is_modpack and - not mod.is_game_content then + if not mod.is_modpack and not mod.always_on then if modname_valid(mod.name) then if mod.enabled then worldfile:set("load_mod_" .. mod.name, mod.virtual_path) @@ -336,18 +325,15 @@ local function handle_buttons(this, fields) -- multiple enables. local was_enabled = {} - for i = 1, #list do - if not list[i].is_game_content - and not list[i].is_modpack and list[i].enabled then - was_enabled[list[i].name] = true + for _, mod in ipairs(list) do + if not mod.always_on and not mod.is_modpack and mod.enabled then + was_enabled[mod.name] = true end end - for i = 1, #list do - if not list[i].is_game_content and not list[i].is_modpack and - not was_enabled[list[i].name] then - list[i].enabled = true - was_enabled[list[i].name] = true + for _, mod in ipairs(list) do + if not mod.always_on and not mod.is_modpack and not was_enabled[mod.name] then + mod.enabled = true end end @@ -358,10 +344,9 @@ local function handle_buttons(this, fields) if fields.btn_disable_all_mods then local list = this.data.list:get_raw_list() - for i = 1, #list do - if not list[i].is_game_content - and not list[i].is_modpack then - list[i].enabled = false + for _, mod in ipairs(list) do + if not mod.always_on and not mod.is_modpack then + mod.enabled = false end end enabled_all = false