]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Mainmenu game-related changes (#11887)
authorsfan5 <sfan5@live.de>
Sun, 9 Jan 2022 20:15:35 +0000 (21:15 +0100)
committerGitHub <noreply@github.com>
Sun, 9 Jan 2022 20:15:35 +0000 (21:15 +0100)
fixes:
* Switching between games does not immediately hide creative mode / damage buttons if so specified
* World creation menu has a game selection list even though the menu already provides a gamebar
* Showing gameid in world list is unnecessary
* Choice of mapgen parameters in menu persists between games (and was half-broken)

builtin/mainmenu/common.lua
builtin/mainmenu/dlg_create_world.lua
builtin/mainmenu/tab_local.lua
src/content/subgames.cpp
src/map_settings_manager.cpp
src/mapgen/mapgen.cpp
src/script/lua_api/l_mainmenu.cpp
src/settings.cpp
src/settings.h

index b36c9596a03aa8edb1c8d94e45bbf1dea13aa8ba..8db8bb8d17f19c0515d980c71da83c1efc2b7c87 100644 (file)
@@ -125,17 +125,21 @@ os.tmpname = function()
 end
 --------------------------------------------------------------------------------
 
-function menu_render_worldlist()
-       local retval = ""
+function menu_render_worldlist(show_gameid)
+       local retval = {}
        local current_worldlist = menudata.worldlist:get_list()
 
+       local row
        for i, v in ipairs(current_worldlist) do
-               if retval ~= "" then retval = retval .. "," end
-               retval = retval .. core.formspec_escape(v.name) ..
-                               " \\[" .. core.formspec_escape(v.gameid) .. "\\]"
+               row = v.name
+               if show_gameid == nil or show_gameid == true then
+                       row = row .. " [" .. v.gameid .. "]"
+               end
+               retval[#retval+1] = core.formspec_escape(row)
+
        end
 
-       return retval
+       return table.concat(retval, ",")
 end
 
 function menu_handle_key_up_down(fields, textlist, settingname)
index 5456eb3ebc3a9c7cc0ec417c79a5a6c38932c1e4..8d1509f33312b905b1b29f9f2f2624a82ff4eb15 100644 (file)
@@ -15,7 +15,8 @@
 --with this program; if not, write to the Free Software Foundation, Inc.,
 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
-local worldname = ""
+-- cf. tab_local, the gamebar already provides game selection so we hide the list from here
+local hide_gamelist = PLATFORM ~= "Android"
 
 local function table_to_flags(ftable)
        -- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves"
@@ -31,9 +32,8 @@ local function strflag(flags, flag)
        return (flags[flag] == true) and "true" or "false"
 end
 
-local cb_caverns = { "caverns", fgettext("Caverns"), "caverns",
+local cb_caverns = { "caverns", fgettext("Caverns"),
        fgettext("Very large caverns deep in the underground") }
-local tt_sea_rivers = fgettext("Sea level rivers")
 
 local flag_checkboxes = {
        v5 = {
@@ -41,39 +41,38 @@ local flag_checkboxes = {
        },
        v7 = {
                cb_caverns,
-               { "ridges", fgettext("Rivers"), "ridges", tt_sea_rivers },
-               { "mountains", fgettext("Mountains"), "mountains" },
-               { "floatlands", fgettext("Floatlands (experimental)"), "floatlands",
+               { "ridges", fgettext("Rivers"), fgettext("Sea level rivers") },
+               { "mountains", fgettext("Mountains") },
+               { "floatlands", fgettext("Floatlands (experimental)"),
                fgettext("Floating landmasses in the sky") },
        },
        carpathian = {
                cb_caverns,
-               { "rivers", fgettext("Rivers"), "rivers", tt_sea_rivers },
+               { "rivers", fgettext("Rivers"), fgettext("Sea level rivers") },
        },
        valleys = {
-               { "altitude-chill", fgettext("Altitude chill"), "altitude_chill",
+               { "altitude_chill", fgettext("Altitude chill"),
                fgettext("Reduces heat with altitude") },
-               { "altitude-dry", fgettext("Altitude dry"), "altitude_dry",
+               { "altitude_dry", fgettext("Altitude dry"),
                fgettext("Reduces humidity with altitude") },
-               { "humid-rivers", fgettext("Humid rivers"), "humid_rivers",
+               { "humid_rivers", fgettext("Humid rivers"),
                fgettext("Increases humidity around rivers") },
-               { "vary-river-depth", fgettext("Vary river depth"), "vary_river_depth",
+               { "vary_river_depth", fgettext("Vary river depth"),
                fgettext("Low humidity and high heat causes shallow or dry rivers") },
        },
        flat = {
                cb_caverns,
-               { "hills", fgettext("Hills"), "hills" },
-               { "lakes", fgettext("Lakes"), "lakes" },
+               { "hills", fgettext("Hills") },
+               { "lakes", fgettext("Lakes") },
        },
        fractal = {
-               { "terrain", fgettext("Additional terrain"), "terrain",
+               { "terrain", fgettext("Additional terrain"),
                fgettext("Generate non-fractal terrain: Oceans and underground") },
        },
        v6 = {
-               { "trees", fgettext("Trees and jungle grass"), "trees" },
-               { "flat", fgettext("Flat terrain"), "flat" },
-               { "mudflow", fgettext("Mud flow"), "mudflow",
-               fgettext("Terrain surface erosion") },
+               { "trees", fgettext("Trees and jungle grass") },
+               { "flat", fgettext("Flat terrain") },
+               { "mudflow", fgettext("Mud flow"), fgettext("Terrain surface erosion") },
                -- Biome settings are in mgv6_biomes below
        },
 }
@@ -105,38 +104,26 @@ local function create_world_formspec(dialogdata)
                        "button[4.75,2.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
        end
 
+       local current_mg = dialogdata.mg
        local mapgens = core.get_mapgen_names()
 
-       local current_seed = core.settings:get("fixed_map_seed") or ""
-       local current_mg   = core.settings:get("mg_name")
        local gameid = core.settings:get("menu_last_game")
 
-       local flags = {
-               main = core.settings:get_flags("mg_flags"),
-               v5 = core.settings:get_flags("mgv5_spflags"),
-               v6 = core.settings:get_flags("mgv6_spflags"),
-               v7 = core.settings:get_flags("mgv7_spflags"),
-               fractal = core.settings:get_flags("mgfractal_spflags"),
-               carpathian = core.settings:get_flags("mgcarpathian_spflags"),
-               valleys = core.settings:get_flags("mgvalleys_spflags"),
-               flat = core.settings:get_flags("mgflat_spflags"),
-       }
-
-       local gameidx = 0
-       if gameid ~= nil then
-               local _
-               _, gameidx = pkgmgr.find_by_gameid(gameid)
+       local flags = dialogdata.flags
 
-               if gameidx == nil then
-                       gameidx = 0
-               end
+       local game, gameidx = pkgmgr.find_by_gameid(gameid)
+       if game == nil and hide_gamelist then
+               -- should never happen but just pick the first game
+               game = pkgmgr.get_game(1)
+               gameidx = 1
+               core.settings:set("menu_last_game", game.id)
+       elseif game == nil then
+               gameidx = 0
        end
 
-       local game_by_gameidx = core.get_game(gameidx)
        local disallowed_mapgen_settings = {}
-       if game_by_gameidx ~= nil then
-               local gamepath = game_by_gameidx.path
-               local gameconfig = Settings(gamepath.."/game.conf")
+       if game ~= nil then
+               local gameconfig = Settings(game.path.."/game.conf")
 
                local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split()
                for key, value in pairs(allowed_mapgens) do
@@ -156,7 +143,7 @@ local function create_world_formspec(dialogdata)
                        end
                end
 
-               if disallowed_mapgens then
+               if #disallowed_mapgens > 0 then
                        for i = #mapgens, 1, -1 do
                                if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then
                                        table.remove(mapgens, i)
@@ -172,23 +159,29 @@ local function create_world_formspec(dialogdata)
 
        local mglist = ""
        local selindex
-       local i = 1
-       local first_mg
-       for k,v in pairs(mapgens) do
-               if not first_mg then
-                       first_mg = v
+       do -- build the list of mapgens
+               local i = 1
+               local first_mg
+               for k, v in pairs(mapgens) do
+                       if not first_mg then
+                               first_mg = v
+                       end
+                       if current_mg == v then
+                               selindex = i
+                       end
+                       i = i + 1
+                       mglist = mglist .. core.formspec_escape(v) .. ","
                end
-               if current_mg == v then
-                       selindex = i
+               if not selindex then
+                       selindex = 1
+                       current_mg = first_mg
                end
-               i = i + 1
-               mglist = mglist .. v .. ","
-       end
-       if not selindex then
-               selindex = 1
-               current_mg = first_mg
+               mglist = mglist:sub(1, -2)
        end
-       mglist = mglist:sub(1, -2)
+
+       -- The logic of the flag element IDs is as follows:
+       -- "flag_main_foo-bar-baz" controls dialogdata.flags["main"]["foo_bar_baz"]
+       -- see the buttonhandler for the implementation of this
 
        local mg_main_flags = function(mapgen, y)
                if mapgen == "singlenode" then
@@ -198,11 +191,11 @@ local function create_world_formspec(dialogdata)
                        return "", y
                end
 
-               local form = "checkbox[0," .. y .. ";flag_mg_caves;" ..
+               local form = "checkbox[0," .. y .. ";flag_main_caves;" ..
                        fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]"
                y = y + 0.5
 
-               form = form .. "checkbox[0,"..y..";flag_mg_dungeons;" ..
+               form = form .. "checkbox[0,"..y..";flag_main_dungeons;" ..
                        fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]"
                y = y + 0.5
 
@@ -213,7 +206,7 @@ local function create_world_formspec(dialogdata)
                else
                        d_tt = fgettext("Structures appearing on the terrain, typically trees and plants")
                end
-               form = form .. "checkbox[0,"..y..";flag_mg_decorations;" ..
+               form = form .. "checkbox[0,"..y..";flag_main_decorations;" ..
                        d_name .. ";" ..
                        strflag(flags.main, "decorations").."]" ..
                        "tooltip[flag_mg_decorations;" ..
@@ -221,7 +214,7 @@ local function create_world_formspec(dialogdata)
                        "]"
                y = y + 0.5
 
-               form = form .. "tooltip[flag_mg_caves;" ..
+               form = form .. "tooltip[flag_main_caves;" ..
                fgettext("Network of tunnels and caves")
                .. "]"
                return form, y
@@ -235,13 +228,13 @@ local function create_world_formspec(dialogdata)
                        return "", y
                end
                local form = ""
-               for _,tab in pairs(flag_checkboxes[mapgen]) do
-                       local id = "flag_mg"..mapgen.."_"..tab[1]
+               for _, tab in pairs(flag_checkboxes[mapgen]) do
+                       local id = "flag_"..mapgen.."_"..tab[1]:gsub("_", "-")
                        form = form .. ("checkbox[0,%f;%s;%s;%s]"):
-                               format(y, id, tab[2], strflag(flags[mapgen], tab[3]))
+                               format(y, id, tab[2], strflag(flags[mapgen], tab[1]))
 
-                       if tab[4] then
-                               form = form .. "tooltip["..id..";"..tab[4].."]"
+                       if tab[3] then
+                               form = form .. "tooltip["..id..";"..tab[3].."]"
                        end
                        y = y + 0.5
                end
@@ -277,16 +270,14 @@ local function create_world_formspec(dialogdata)
 
                -- biomeblend
                y = y + 0.55
-               form = form .. "checkbox[0,"..y..";flag_mgv6_biomeblend;" ..
+               form = form .. "checkbox[0,"..y..";flag_v6_biomeblend;" ..
                        fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" ..
-                       "tooltip[flag_mgv6_biomeblend;" ..
+                       "tooltip[flag_v6_biomeblend;" ..
                        fgettext("Smooth transition between biomes") .. "]"
 
                return form, y
        end
 
-       current_seed = core.formspec_escape(current_seed)
-
        local y_start = 0.0
        local y = y_start
        local str_flags, str_spflags
@@ -323,21 +314,27 @@ local function create_world_formspec(dialogdata)
                "container[0,0]"..
                "field[0.3,0.6;6,0.5;te_world_name;" ..
                fgettext("World name") ..
-               ";" .. core.formspec_escape(worldname) .. "]" ..
+               ";" .. core.formspec_escape(dialogdata.worldname) .. "]" ..
+               "set_focus[te_world_name;false]" ..
 
                "field[0.3,1.7;6,0.5;te_seed;" ..
                fgettext("Seed") ..
-               ";".. current_seed .. "]" ..
+               ";".. core.formspec_escape(dialogdata.seed) .. "]" ..
 
                "label[0,2;" .. fgettext("Mapgen") .. "]"..
-               "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
+               "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]"
+
+       if not hide_gamelist or devtest_only ~= "" then
+               retval = retval ..
+                       "label[0,3.35;" .. fgettext("Game") .. "]"..
+                       "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
+                       pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
+                       "container[0,4.5]" ..
+                       devtest_only ..
+                       "container_end[]"
+       end
 
-               "label[0,3.35;" .. fgettext("Game") .. "]"..
-               "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
-               pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
-               "container[0,4.5]" ..
-               devtest_only ..
-               "container_end[]" ..
+       retval = retval ..
                "container_end[]" ..
 
                -- Right side
@@ -360,9 +357,20 @@ local function create_world_buttonhandler(this, fields)
                fields["key_enter"] then
 
                local worldname = fields["te_world_name"]
-               local gameindex = core.get_textlist_index("games")
+               local game, gameindex
+               if hide_gamelist then
+                       game, gameindex = pkgmgr.find_by_gameid(core.settings:get("menu_last_game"))
+               else
+                       gameindex = core.get_textlist_index("games")
+                       game = pkgmgr.get_game(gameindex)
+               end
 
-               if gameindex ~= nil then
+               local message
+               if game == nil then
+                       message = fgettext("No game selected")
+               end
+
+               if message == nil then
                        -- For unnamed worlds use the generated name 'world<number>',
                        -- where the number increments: it is set to 1 larger than the largest
                        -- generated name number found.
@@ -377,36 +385,48 @@ local function create_world_buttonhandler(this, fields)
                                worldname = "world" .. worldnum_max + 1
                        end
 
-                       core.settings:set("fixed_map_seed", fields["te_seed"])
-
-                       local message
-                       if not menudata.worldlist:uid_exists_raw(worldname) then
-                               core.settings:set("mg_name",fields["dd_mapgen"])
-                               message = core.create_world(worldname,gameindex)
-                       else
+                       if menudata.worldlist:uid_exists_raw(worldname) then
                                message = fgettext("A world named \"$1\" already exists", worldname)
                        end
+               end
 
-                       if message ~= nil then
-                               gamedata.errormessage = message
-                       else
-                               core.settings:set("menu_last_game",pkgmgr.games[gameindex].id)
-                               if this.data.update_worldlist_filter then
-                                       menudata.worldlist:set_filtercriteria(pkgmgr.games[gameindex].id)
-                                       mm_game_theme.update("singleplayer", pkgmgr.games[gameindex].id)
-                               end
-                               menudata.worldlist:refresh()
-                               core.settings:set("mainmenu_last_selected_world",
-                                                                       menudata.worldlist:raw_index_by_uid(worldname))
+               if message == nil then
+                       this.data.seed = fields["te_seed"]
+                       this.data.mg = fields["dd_mapgen"]
+
+                       -- actual names as used by engine
+                       local settings = {
+                               fixed_map_seed = this.data.seed,
+                               mg_name = this.data.mg,
+                               mg_flags = table_to_flags(this.data.flags.main),
+                               mgv5_spflags = table_to_flags(this.data.flags.v5),
+                               mgv6_spflags = table_to_flags(this.data.flags.v6),
+                               mgv7_spflags = table_to_flags(this.data.flags.v7),
+                               mgfractal_spflags = table_to_flags(this.data.flags.fractal),
+                               mgcarpathian_spflags = table_to_flags(this.data.flags.carpathian),
+                               mgvalleys_spflags = table_to_flags(this.data.flags.valleys),
+                               mgflat_spflags = table_to_flags(this.data.flags.flat),
+                       }
+                       message = core.create_world(worldname, gameindex, settings)
+               end
+
+               if message == nil then
+                       core.settings:set("menu_last_game", game.id)
+                       if this.data.update_worldlist_filter then
+                               menudata.worldlist:set_filtercriteria(game.id)
                        end
-               else
-                       gamedata.errormessage = fgettext("No game selected")
+                       menudata.worldlist:refresh()
+                       core.settings:set("mainmenu_last_selected_world",
+                                       menudata.worldlist:raw_index_by_uid(worldname))
                end
+
+               gamedata.errormessage = message
                this:delete()
                return true
        end
 
-       worldname = fields.te_world_name
+       this.data.worldname = fields["te_world_name"]
+       this.data.seed = fields["te_seed"]
 
        if fields["games"] then
                local gameindex = core.get_textlist_index("games")
@@ -417,22 +437,11 @@ local function create_world_buttonhandler(this, fields)
        for k,v in pairs(fields) do
                local split = string.split(k, "_", nil, 3)
                if split and split[1] == "flag" then
-                       local setting
-                       if split[2] == "mg" then
-                               setting = "mg_flags"
-                       else
-                               setting = split[2].."_spflags"
-                       end
                        -- We replaced the underscore of flag names with a dash.
                        local flag = string.gsub(split[3], "-", "_")
-                       local ftable = core.settings:get_flags(setting)
-                       if v == "true" then
-                               ftable[flag] = true
-                       else
-                               ftable[flag] = false
-                       end
-                       local flags = table_to_flags(ftable)
-                       core.settings:set(setting, flags)
+                       local ftable = this.data.flags[split[2]]
+                       assert(ftable)
+                       ftable[flag] = v == "true"
                        return true
                end
        end
@@ -446,18 +455,16 @@ local function create_world_buttonhandler(this, fields)
                local entry = core.formspec_escape(fields["mgv6_biomes"])
                for b=1, #mgv6_biomes do
                        if entry == mgv6_biomes[b][1] then
-                               local ftable = core.settings:get_flags("mgv6_spflags")
+                               local ftable = this.data.flags.v6
                                ftable.jungles = mgv6_biomes[b][2].jungles
                                ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes
-                               local flags = table_to_flags(ftable)
-                               core.settings:set("mgv6_spflags", flags)
                                return true
                        end
                end
        end
 
        if fields["dd_mapgen"] then
-               core.settings:set("mg_name", fields["dd_mapgen"])
+               this.data.mg = fields["dd_mapgen"]
                return true
        end
 
@@ -466,12 +473,27 @@ end
 
 
 function create_create_world_dlg(update_worldlistfilter)
-       worldname = ""
        local retval = dialog_create("sp_create_world",
                                        create_world_formspec,
                                        create_world_buttonhandler,
                                        nil)
-       retval.update_worldlist_filter = update_worldlistfilter
+       retval.data = {
+               update_worldlist_filter = update_worldlistfilter,
+               worldname = "",
+               -- settings the world is created with:
+               seed = core.settings:get("fixed_map_seed") or "",
+               mg = core.settings:get("mg_name"),
+               flags = {
+                       main = core.settings:get_flags("mg_flags"),
+                       v5 = core.settings:get_flags("mgv5_spflags"),
+                       v6 = core.settings:get_flags("mgv6_spflags"),
+                       v7 = core.settings:get_flags("mgv7_spflags"),
+                       fractal = core.settings:get_flags("mgfractal_spflags"),
+                       carpathian = core.settings:get_flags("mgcarpathian_spflags"),
+                       valleys = core.settings:get_flags("mgvalleys_spflags"),
+                       flat = core.settings:get_flags("mgflat_spflags"),
+               }
+       }
 
        return retval
 end
index 2d1a616a80e352936f6fa5e2a2bbbc232055152e..e77c6f04de368ea1e967099144003f04e4e244e8 100644 (file)
@@ -33,10 +33,30 @@ if enable_gamebar then
                return game
        end
 
+       -- Apply menu changes from given game
+       function apply_game(game)
+               core.set_topleft_text(game.name)
+               core.settings:set("menu_last_game", game.id)
+               menudata.worldlist:set_filtercriteria(game.id)
+
+               mm_game_theme.update("singleplayer", game) -- this refreshes the formspec
+
+               local index = filterlist.get_current_index(menudata.worldlist,
+                       tonumber(core.settings:get("mainmenu_last_selected_world")))
+               if not index or index < 1 then
+                       local selected = core.get_textlist_index("sp_worlds")
+                       if selected ~= nil and selected < #menudata.worldlist:get_list() then
+                               index = selected
+                       else
+                               index = #menudata.worldlist:get_list()
+                       end
+               end
+               menu_worldmt_legacy(index)
+       end
+
        function singleplayer_refresh_gamebar()
 
                local old_bar = ui.find_by_name("game_button_bar")
-
                if old_bar ~= nil then
                        old_bar:delete()
                end
@@ -51,26 +71,10 @@ if enable_gamebar then
                                return true
                        end
 
-                       for key,value in pairs(fields) do
-                               for j=1,#pkgmgr.games,1 do
-                                       if ("game_btnbar_" .. pkgmgr.games[j].id == key) then
-                                               mm_game_theme.update("singleplayer", pkgmgr.games[j])
-                                               core.set_topleft_text(pkgmgr.games[j].name)
-                                               core.settings:set("menu_last_game",pkgmgr.games[j].id)
-                                               menudata.worldlist:set_filtercriteria(pkgmgr.games[j].id)
-                                               local index = filterlist.get_current_index(menudata.worldlist,
-                                                       tonumber(core.settings:get("mainmenu_last_selected_world")))
-                                               if not index or index < 1 then
-                                                       local selected = core.get_textlist_index("sp_worlds")
-                                                       if selected ~= nil and selected < #menudata.worldlist:get_list() then
-                                                               index = selected
-                                                       else
-                                                               index = #menudata.worldlist:get_list()
-                                                       end
-                                               end
-                                               menu_worldmt_legacy(index)
-                                               return true
-                                       end
+                       for _, game in ipairs(pkgmgr.games) do
+                               if fields["game_btnbar_" .. game.id] then
+                                       apply_game(game)
+                                       return true
                                end
                        end
                end
@@ -79,25 +83,22 @@ if enable_gamebar then
                        game_buttonbar_button_handler,
                        {x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15})
 
-               for i=1,#pkgmgr.games,1 do
-                       local btn_name = "game_btnbar_" .. pkgmgr.games[i].id
+               for _, game in ipairs(pkgmgr.games) do
+                       local btn_name = "game_btnbar_" .. game.id
 
                        local image = nil
                        local text = nil
-                       local tooltip = core.formspec_escape(pkgmgr.games[i].name)
+                       local tooltip = core.formspec_escape(game.name)
 
-                       if pkgmgr.games[i].menuicon_path ~= nil and
-                               pkgmgr.games[i].menuicon_path ~= "" then
-                               image = core.formspec_escape(pkgmgr.games[i].menuicon_path)
+                       if (game.menuicon_path or "") ~= "" then
+                               image = core.formspec_escape(game.menuicon_path)
                        else
-
-                               local part1 = pkgmgr.games[i].id:sub(1,5)
-                               local part2 = pkgmgr.games[i].id:sub(6,10)
-                               local part3 = pkgmgr.games[i].id:sub(11)
+                               local part1 = game.id:sub(1,5)
+                               local part2 = game.id:sub(6,10)
+                               local part3 = game.id:sub(11)
 
                                text = part1 .. "\n" .. part2
-                               if part3 ~= nil and
-                                       part3 ~= "" then
+                               if part3 ~= "" then
                                        text = text .. "\n" .. part3
                                end
                        end
@@ -147,8 +148,12 @@ local function get_formspec(tabview, name, tabdata)
                                tonumber(core.settings:get("mainmenu_last_selected_world")))
        local list = menudata.worldlist:get_list()
        local world = list and index and list[index]
-       local gameid = world and world.gameid
-       local game = gameid and pkgmgr.find_by_gameid(gameid)
+       local game
+       if world then
+               game = pkgmgr.find_by_gameid(world.gameid)
+       else
+               game = current_game()
+       end
        local disabled_settings = get_disabled_settings(game)
 
        local creative, damage, host = "", "", ""
@@ -182,7 +187,7 @@ local function get_formspec(tabview, name, tabdata)
                        damage ..
                        host ..
                        "textlist[3.9,0.4;7.9,3.45;sp_worlds;" ..
-                       menu_render_worldlist() ..
+                       menu_render_worldlist(not enable_gamebar) ..
                        ";" .. index .. "]"
 
        if core.settings:get_bool("enable_server") and disabled_settings["enable_server"] == nil then
@@ -319,7 +324,7 @@ local function main_button_handler(this, fields, name, tabdata)
        end
 
        if fields["world_create"] ~= nil then
-               local create_world_dlg = create_create_world_dlg(true)
+               local create_world_dlg = create_create_world_dlg(enable_gamebar)
                create_world_dlg:set_parent(this)
                this:hide()
                create_world_dlg:show()
@@ -371,11 +376,8 @@ if enable_gamebar then
        function on_change(type, old_tab, new_tab)
                if (type == "ENTER") then
                        local game = current_game()
-
                        if game then
-                               menudata.worldlist:set_filtercriteria(game.id)
-                               core.set_topleft_text(game.name)
-                               mm_game_theme.update("singleplayer",game)
+                               apply_game(game)
                        end
 
                        singleplayer_refresh_gamebar()
index e834f40cd355c29e22d31866c27dcd299261f0a6..62e82e0e4a29235a255460213c5ff25dee3821f9 100644 (file)
@@ -24,7 +24,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "util/strfnd.h"
 #include "defaultsettings.h" // for set_default_settings
-#include "mapgen/mapgen.h"   // for MapgenParams
+#include "map_settings_manager.h"
 #include "util/string.h"
 
 #ifndef SERVER
@@ -370,19 +370,12 @@ void loadGameConfAndInitWorld(const std::string &path, const std::string &name,
        // Create map_meta.txt if does not already exist
        std::string map_meta_path = final_path + DIR_DELIM + "map_meta.txt";
        if (!fs::PathExists(map_meta_path)) {
-               verbosestream << "Creating map_meta.txt (" << map_meta_path << ")"
-                             << std::endl;
-               std::ostringstream oss(std::ios_base::binary);
+               MapSettingsManager mgr(map_meta_path);
 
-               Settings conf;
-               MapgenParams params;
-
-               params.readParams(g_settings);
-               params.writeParams(&conf);
-               conf.writeLines(oss);
-               oss << "[end_of_params]\n";
+               mgr.setMapSetting("seed", g_settings->get("fixed_map_seed"));
 
-               fs::safeWriteToFile(map_meta_path, oss.str());
+               mgr.makeMapgenParams();
+               mgr.saveMapMeta();
        }
 
        // The Settings object is no longer needed for created worlds
index 7e86a99379153e9e85c0b7305122ee39bf1f153b..c75483edb4cc96db5450a29c4391ec9d0133c0bd 100644 (file)
@@ -52,14 +52,7 @@ MapSettingsManager::~MapSettingsManager()
 bool MapSettingsManager::getMapSetting(
        const std::string &name, std::string *value_out)
 {
-       // Try getting it normally first
-       if (m_map_settings->getNoEx(name, *value_out))
-               return true;
-
-       // If not we may have to resolve some compatibility kludges
-       if (name == "seed")
-               return Settings::getLayer(SL_GLOBAL)->getNoEx("fixed_map_seed", *value_out);
-       return false;
+       return m_map_settings->getNoEx(name, *value_out);
 }
 
 
index 7984ff609287031d86c7adef5454b5147f62108d..d767bd264dd350b8741842581ed4719ada575e64 100644 (file)
@@ -1018,10 +1018,11 @@ MapgenParams::~MapgenParams()
 
 void MapgenParams::readParams(const Settings *settings)
 {
-       std::string seed_str;
-       const char *seed_name = (settings == g_settings) ? "fixed_map_seed" : "seed";
+       // should always be used via MapSettingsManager
+       assert(settings != g_settings);
 
-       if (settings->getNoEx(seed_name, seed_str)) {
+       std::string seed_str;
+       if (settings->getNoEx("seed", seed_str)) {
                if (!seed_str.empty())
                        seed = read_seed(seed_str.c_str());
                else
index 3d80bdafa17c7e86e10a1b83534af7b29ff4af38..736ad022fdfd6c41d84bf88093e4776426c2ca79 100644 (file)
@@ -414,25 +414,53 @@ int ModApiMainMenu::l_create_world(lua_State *L)
        const char *name        = luaL_checkstring(L, 1);
        int gameidx                     = luaL_checkinteger(L,2) -1;
 
+       StringMap use_settings;
+       luaL_checktype(L, 3, LUA_TTABLE);
+       lua_pushnil(L);
+       while (lua_next(L, 3) != 0) {
+               // key at index -2 and value at index -1
+               use_settings[luaL_checkstring(L, -2)] = luaL_checkstring(L, -1);
+               lua_pop(L, 1);
+       }
+       lua_pop(L, 1);
+
        std::string path = porting::path_user + DIR_DELIM
                        "worlds" + DIR_DELIM
                        + sanitizeDirName(name, "world_");
 
        std::vector<SubgameSpec> games = getAvailableGames();
+       if (gameidx < 0 || gameidx >= (int) games.size()) {
+               lua_pushstring(L, "Invalid game index");
+               return 1;
+       }
 
-       if ((gameidx >= 0) &&
-                       (gameidx < (int) games.size())) {
+       // Set the settings for world creation
+       // this is a bad hack but the best we have right now..
+       StringMap backup;
+       for (auto it : use_settings) {
+               if (g_settings->existsLocal(it.first))
+                       backup[it.first] = g_settings->get(it.first);
+               g_settings->set(it.first, it.second);
+       }
 
-               // Create world if it doesn't exist
-               try {
-                       loadGameConfAndInitWorld(path, name, games[gameidx], true);
-                       lua_pushnil(L);
-               } catch (const BaseException &e) {
-                       lua_pushstring(L, (std::string("Failed to initialize world: ") + e.what()).c_str());
-               }
-       } else {
-               lua_pushstring(L, "Invalid game index");
+       // Create world if it doesn't exist
+       try {
+               loadGameConfAndInitWorld(path, name, games[gameidx], true);
+               lua_pushnil(L);
+       } catch (const BaseException &e) {
+               auto err = std::string("Failed to initialize world: ") + e.what();
+               lua_pushstring(L, err.c_str());
        }
+
+       // Restore previous settings
+       for (auto it : use_settings) {
+               auto it2 = backup.find(it.first);
+               if (it2 == backup.end())
+                       g_settings->remove(it.first); // wasn't set before
+               else
+                       g_settings->set(it.first, it2->second); // was set before
+       }
+
        return 1;
 }
 
index cf7ec1b721d0f351647e7778295db52400d677a9..0e44ee0bcb6c9adbc7915d228843a8c5fd85298d 100644 (file)
@@ -659,9 +659,7 @@ bool Settings::getNoiseParamsFromGroup(const std::string &name,
 
 bool Settings::exists(const std::string &name) const
 {
-       MutexAutoLock lock(m_mutex);
-
-       if (m_settings.find(name) != m_settings.end())
+       if (existsLocal(name))
                return true;
        if (auto parent = getParent())
                return parent->exists(name);
@@ -669,6 +667,14 @@ bool Settings::exists(const std::string &name) const
 }
 
 
+bool Settings::existsLocal(const std::string &name) const
+{
+       MutexAutoLock lock(m_mutex);
+
+       return m_settings.find(name) != m_settings.end();
+}
+
+
 std::vector<std::string> Settings::getNames() const
 {
        MutexAutoLock lock(m_mutex);
index 4e32a34881094582246e68820aff5ad8c8955b03..767d057f9c1b77eb4b11e7fe4095121a32eb0aa3 100644 (file)
@@ -172,9 +172,12 @@ class Settings {
        bool getNoiseParamsFromValue(const std::string &name, NoiseParams &np) const;
        bool getNoiseParamsFromGroup(const std::string &name, NoiseParams &np) const;
 
-       // return all keys used
+       // return all keys used in this object
        std::vector<std::string> getNames() const;
+       // check if setting exists anywhere in the hierarchy
        bool exists(const std::string &name) const;
+       // check if setting exists in this object ("locally")
+       bool existsLocal(const std::string &name) const;
 
 
        /***************************************