From 9fd38b64ba32cbfe9e6aaba0b21d5124f3d26494 Mon Sep 17 00:00:00 2001 From: LoneWolfHT Date: Mon, 14 Oct 2024 17:27:18 -0700 Subject: [PATCH] Add support for mods adding their own maps --- mods/ctf/ctf_map/init.lua | 30 +++++++++++++++++++++++++++ mods/ctf/ctf_map/map_functions.lua | 2 +- mods/ctf/ctf_map/map_meta.lua | 10 +++++---- mods/ctf/ctf_map/mapedit_gui.lua | 26 +++++++++++------------ mods/ctf/ctf_modebase/map_catalog.lua | 11 +++++----- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/mods/ctf/ctf_map/init.lua b/mods/ctf/ctf_map/init.lua index 9af7215e3..b66f0f2be 100644 --- a/mods/ctf/ctf_map/init.lua +++ b/mods/ctf/ctf_map/init.lua @@ -27,8 +27,38 @@ ctf_map = { math.floor((time % 3600) / 60), -- minutes math.floor(time % 60)) -- seconds end, + + -- List of registered map folder names. Use `ctf_map.map_path` to get the path + registered_maps = {}, + + -- Table of map paths. Indexed by map's folder name + -- Doesn't include trailing '/' + map_path = {}, } +function ctf_map.register_map(dirname, path_to_map) + if path_to_map:sub(-1) ~= "/" then + path_to_map = path_to_map .. "/" + end + + assert(table.indexof(ctf_map.registered_maps, dirname) == -1, "Duplicate map detected: "..path_to_map) + + table.insert(ctf_map.registered_maps, dirname) + ctf_map.map_path[dirname] = path_to_map .. dirname +end + +function ctf_map.register_maps_dir(path_to_folder) + if path_to_folder:sub(-1) ~= "/" then + path_to_folder = path_to_folder .. "/" + end + + for _, mapdir in pairs(minetest.get_dir_list(path_to_folder, true)) do + ctf_map.register_map(mapdir, path_to_folder) + end +end + +ctf_map.register_maps_dir(ctf_map.maps_dir) + ctf_api.register_on_match_start(function() ctf_map.start_time = os.time() end) diff --git a/mods/ctf/ctf_map/map_functions.lua b/mods/ctf/ctf_map/map_functions.lua index 53f42e288..496da71df 100644 --- a/mods/ctf/ctf_map/map_functions.lua +++ b/mods/ctf/ctf_map/map_functions.lua @@ -9,7 +9,7 @@ end function ctf_map.place_map(mapmeta, callback) local dirname = mapmeta.dirname - local schempath = ctf_map.maps_dir .. dirname .. "/map.mts" + local schempath = ctf_map.map_path[dirname] .. "/map.mts" local barrier_data = mapmeta.barriers and mapmeta.barriers() diff --git a/mods/ctf/ctf_map/map_meta.lua b/mods/ctf/ctf_map/map_meta.lua index 7b2e1d759..4aac16868 100644 --- a/mods/ctf/ctf_map/map_meta.lua +++ b/mods/ctf/ctf_map/map_meta.lua @@ -64,7 +64,9 @@ local function connect_barriers_file(map_name, offset, barriers_filepath) end function ctf_map.load_map_meta(idx, dirname) - local meta = Settings(ctf_map.maps_dir .. dirname .. "/map.conf") + assert(ctf_map.map_path[dirname], "Map "..dirname.." not found") + + local meta = Settings(ctf_map.map_path[dirname] .. "/map.conf") if not meta then error("Map '"..dump(dirname).."' not found") end @@ -75,7 +77,7 @@ function ctf_map.load_map_meta(idx, dirname) if not meta:get("map_version") then if not meta:get("r") then - error("Map was not properly configured: " .. ctf_map.maps_dir .. dirname .. "/map.conf") + error("Map was not properly configured: " .. ctf_map.map_path[dirname] .. "/map.conf") end local mapr = meta:get("r") @@ -198,7 +200,7 @@ function ctf_map.load_map_meta(idx, dirname) enable_shadows = tonumber(meta:get("enable_shadows") or "0.26"), } if tonumber(meta:get("map_version")) >= 3 and not ctf_core.settings.low_ram_mode then - map.barriers = connect_barriers_file(dirname, offset, ctf_map.maps_dir .. dirname .. "/barriers.data") + map.barriers = connect_barriers_file(dirname, offset, ctf_map.map_path[dirname] .. "/barriers.data") end for id, def in pairs(map.chests) do @@ -223,7 +225,7 @@ function ctf_map.load_map_meta(idx, dirname) map.flag_center = calc_flag_center(map) - if ctf_map.skybox_exists(ctf_map.maps_dir .. dirname) then + if ctf_map.skybox_exists(ctf_map.map_path[dirname]) then skybox.add({dirname, "#ffffff", [5] = "png"}) map.skybox = dirname diff --git a/mods/ctf/ctf_map/mapedit_gui.lua b/mods/ctf/ctf_map/mapedit_gui.lua index 1df67237b..be4e6ed14 100644 --- a/mods/ctf/ctf_map/mapedit_gui.lua +++ b/mods/ctf/ctf_map/mapedit_gui.lua @@ -74,10 +74,10 @@ local function dothenext(time, dir, func) end ctf_map.register_map_command("resave_all", function(name, params) - local dirlist = minetest.get_dir_list(ctf_map.maps_dir, true) + local maplist = table.copy(ctf_map.registered_maps) dothenext(1, 1, function(next, dir) - if not dirlist[dir] then + if not maplist[dir] then minetest.chat_send_player( name, minetest.colorize("green", "\nMap resaving done.\n") @@ -85,7 +85,7 @@ ctf_map.register_map_command("resave_all", function(name, params) return end - local map = ctf_map.load_map_meta(dir, dirlist[dir]) + local map = ctf_map.load_map_meta(dir, maplist[dir]) if map.enabled then @@ -117,9 +117,9 @@ function ctf_map.show_map_editor(player) return end - local dirlist = minetest.get_dir_list(ctf_map.maps_dir, true) - local dirlist_sorted = dirlist - table.sort(dirlist_sorted) + local maplist = table.copy(ctf_map.registered_maps) + local maplist_sorted = maplist + table.sort(maplist_sorted) local selected_map = 1 ctf_gui.old_show_formspec(player, "ctf_map:start", { @@ -175,7 +175,7 @@ function ctf_map.show_map_editor(player) type = "textlist", pos = {"center", 1.7}, size = {6, 6}, - items = dirlist_sorted, + items = maplist_sorted, func = function(pname, fields) local event = minetest.explode_textlist_event(fields.currentmaps) @@ -192,13 +192,13 @@ function ctf_map.show_map_editor(player) ctf_gui.old_show_formspec(pname, "ctf_map:loading", { size = {x = 6, y = 4}, title = "Capture The Flag Map Editor", - description = "Placing map '"..dirlist_sorted[selected_map].."'. This will take a few seconds..." + description = "Placing map '"..maplist_sorted[selected_map].."'. This will take a few seconds..." }) end) minetest.after(0.5, function() - local idx = table.indexof(dirlist, dirlist_sorted[selected_map]) - local map = ctf_map.load_map_meta(idx, dirlist_sorted[selected_map]) + local idx = table.indexof(maplist, maplist_sorted[selected_map]) + local map = ctf_map.load_map_meta(idx, maplist_sorted[selected_map]) ctf_map.place_map(map, function() minetest.after(2, edit_map, pname, map) @@ -214,14 +214,14 @@ function ctf_map.show_map_editor(player) ctf_gui.old_show_formspec(pname, "ctf_map:loading", { size = {x = 6, y = 4}, title = "Capture The Flag Map Editor", - description = "Resuming map '"..dirlist_sorted[selected_map].. + description = "Resuming map '"..maplist_sorted[selected_map].. "'.\n(Remember that this doesn't recall setting changes)" }) end) minetest.after(0.5, function() - local idx = table.indexof(dirlist, dirlist_sorted[selected_map]) - local map = ctf_map.load_map_meta(idx, dirlist_sorted[selected_map]) + local idx = table.indexof(maplist, maplist_sorted[selected_map]) + local map = ctf_map.load_map_meta(idx, maplist_sorted[selected_map]) minetest.after(2, edit_map, pname, map) end) diff --git a/mods/ctf/ctf_modebase/map_catalog.lua b/mods/ctf/ctf_modebase/map_catalog.lua index a97bb029b..3c1ff9424 100644 --- a/mods/ctf/ctf_modebase/map_catalog.lua +++ b/mods/ctf/ctf_modebase/map_catalog.lua @@ -11,10 +11,9 @@ local used_maps_idx = 1 local map_repeat_interval local function init() - local maps = minetest.get_dir_list(ctf_map.maps_dir, true) - table.sort(maps) + table.sort(ctf_map.registered_maps) - for i, dirname in ipairs(maps) do + for i, dirname in ipairs(ctf_map.registered_maps) do local map = ctf_map.load_map_meta(i, dirname) if map.map_version and map.enabled then table.insert(ctf_modebase.map_catalog.maps, map) @@ -30,8 +29,10 @@ local function init() map_repeat_interval = math.floor(#ctf_modebase.map_catalog.maps / 2) end -init() -assert(#ctf_modebase.map_catalog.maps > 0 or ctf_core.settings.server_mode == "mapedit") +minetest.register_on_mods_loaded(function() + init() + assert(#ctf_modebase.map_catalog.maps > 0 or ctf_core.settings.server_mode == "mapedit") +end) function ctf_modebase.map_catalog.select_map(filter) local maps = {}