2 --Copyright (C) 2014 sapier
4 --This program is free software; you can redistribute it and/or modify
5 --it under the terms of the GNU Lesser General Public License as published by
6 --the Free Software Foundation; either version 2.1 of the License, or
7 --(at your option) any later version.
9 --This program is distributed in the hope that it will be useful,
10 --but WITHOUT ANY WARRANTY; without even the implied warranty of
11 --MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 --GNU Lesser General Public License for more details.
14 --You should have received a copy of the GNU Lesser General Public License along
15 --with this program; if not, write to the Free Software Foundation, Inc.,
16 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 local function table_to_flags(ftable)
21 -- Convert e.g. { jungles = true, caves = false } to "jungles,nocaves"
23 for flag, is_set in pairs(ftable) do
24 str[#str + 1] = is_set and flag or ("no" .. flag)
26 return table.concat(str, ",")
29 -- Same as check_flag but returns a string
30 local function strflag(flags, flag)
31 return (flags[flag] == true) and "true" or "false"
34 local cb_caverns = { "caverns", fgettext("Caverns"), "caverns",
35 fgettext("Very large caverns deep in the underground") }
36 local tt_sea_rivers = fgettext("Sea level rivers")
38 local flag_checkboxes = {
44 { "ridges", fgettext("Rivers"), "ridges", tt_sea_rivers },
45 { "mountains", fgettext("Mountains"), "mountains" },
46 { "floatlands", fgettext("Floatlands (experimental)"), "floatlands",
47 fgettext("Floating landmasses in the sky") },
51 { "rivers", fgettext("Rivers"), "rivers", tt_sea_rivers },
54 { "altitude-chill", fgettext("Altitude chill"), "altitude_chill",
55 fgettext("Reduces heat with altitude") },
56 { "altitude-dry", fgettext("Altitude dry"), "altitude_dry",
57 fgettext("Reduces humidity with altitude") },
58 { "humid-rivers", fgettext("Humid rivers"), "humid_rivers",
59 fgettext("Increases humidity around rivers") },
60 { "vary-river-depth", fgettext("Vary river depth"), "vary_river_depth",
61 fgettext("Low humidity and high heat causes shallow or dry rivers") },
64 { "hills", fgettext("Hills"), "hills" },
65 { "lakes", fgettext("Lakes"), "lakes" },
68 { "terrain", fgettext("Additional terrain"), "terrain",
69 fgettext("Generate non-fractal terrain: Oceans and underground") },
72 { "trees", fgettext("Trees and jungle grass"), "trees" },
73 { "flat", fgettext("Flat terrain"), "flat" },
74 { "mudflow", fgettext("Mud flow"), "mudflow",
75 fgettext("Terrain surface erosion") },
76 -- Biome settings are in mgv6_biomes below
82 fgettext("Temperate, Desert, Jungle, Tundra, Taiga"),
83 {jungles = true, snowbiomes = true}
86 fgettext("Temperate, Desert, Jungle"),
87 {jungles = true, snowbiomes = false}
90 fgettext("Temperate, Desert"),
91 {jungles = false, snowbiomes = false}
95 local function create_world_formspec(dialogdata)
97 -- Error out when no games found
98 if #pkgmgr.games == 0 then
99 return "size[12.25,3,true]" ..
100 "box[0,0;12,2;#ff8800]" ..
101 "textarea[0.3,0;11.7,2;;;"..
102 fgettext("You have no games installed.") .. "\n" ..
103 fgettext("Download one from minetest.net") .. "]" ..
104 "button[4.75,2.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
107 local mapgens = core.get_mapgen_names()
109 local current_seed = core.settings:get("fixed_map_seed") or ""
110 local current_mg = core.settings:get("mg_name")
111 local gameid = core.settings:get("menu_last_game")
114 main = core.settings:get_flags("mg_flags"),
115 v5 = core.settings:get_flags("mgv5_spflags"),
116 v6 = core.settings:get_flags("mgv6_spflags"),
117 v7 = core.settings:get_flags("mgv7_spflags"),
118 fractal = core.settings:get_flags("mgfractal_spflags"),
119 carpathian = core.settings:get_flags("mgcarpathian_spflags"),
120 valleys = core.settings:get_flags("mgvalleys_spflags"),
121 flat = core.settings:get_flags("mgflat_spflags"),
125 if gameid ~= nil then
127 _, gameidx = pkgmgr.find_by_gameid(gameid)
129 if gameidx == nil then
134 local game_by_gameidx = core.get_game(gameidx)
135 local disallowed_mapgen_settings = {}
136 if game_by_gameidx ~= nil then
137 local gamepath = game_by_gameidx.path
138 local gameconfig = Settings(gamepath.."/game.conf")
140 local allowed_mapgens = (gameconfig:get("allowed_mapgens") or ""):split()
141 for key, value in pairs(allowed_mapgens) do
142 allowed_mapgens[key] = value:trim()
145 local disallowed_mapgens = (gameconfig:get("disallowed_mapgens") or ""):split()
146 for key, value in pairs(disallowed_mapgens) do
147 disallowed_mapgens[key] = value:trim()
150 if #allowed_mapgens > 0 then
151 for i = #mapgens, 1, -1 do
152 if table.indexof(allowed_mapgens, mapgens[i]) == -1 then
153 table.remove(mapgens, i)
158 if disallowed_mapgens then
159 for i = #mapgens, 1, -1 do
160 if table.indexof(disallowed_mapgens, mapgens[i]) > 0 then
161 table.remove(mapgens, i)
166 local ds = (gameconfig:get("disallowed_mapgen_settings") or ""):split()
167 for _, value in pairs(ds) do
168 disallowed_mapgen_settings[value:trim()] = true
176 for k,v in pairs(mapgens) do
180 if current_mg == v then
184 mglist = mglist .. v .. ","
188 current_mg = first_mg
190 mglist = mglist:sub(1, -2)
192 local mg_main_flags = function(mapgen, y)
193 if mapgen == "singlenode" then
196 if disallowed_mapgen_settings["mg_flags"] then
200 local form = "checkbox[0," .. y .. ";flag_mg_caves;" ..
201 fgettext("Caves") .. ";"..strflag(flags.main, "caves").."]"
204 form = form .. "checkbox[0,"..y..";flag_mg_dungeons;" ..
205 fgettext("Dungeons") .. ";"..strflag(flags.main, "dungeons").."]"
208 local d_name = fgettext("Decorations")
210 if mapgen == "v6" then
211 d_tt = fgettext("Structures appearing on the terrain (no effect on trees and jungle grass created by v6)")
213 d_tt = fgettext("Structures appearing on the terrain, typically trees and plants")
215 form = form .. "checkbox[0,"..y..";flag_mg_decorations;" ..
217 strflag(flags.main, "decorations").."]" ..
218 "tooltip[flag_mg_decorations;" ..
223 form = form .. "tooltip[flag_mg_caves;" ..
224 fgettext("Network of tunnels and caves")
229 local mg_specific_flags = function(mapgen, y)
230 if not flag_checkboxes[mapgen] then
233 if disallowed_mapgen_settings["mg"..mapgen.."_spflags"] then
237 for _,tab in pairs(flag_checkboxes[mapgen]) do
238 local id = "flag_mg"..mapgen.."_"..tab[1]
239 form = form .. ("checkbox[0,%f;%s;%s;%s]"):
240 format(y, id, tab[2], strflag(flags[mapgen], tab[3]))
243 form = form .. "tooltip["..id..";"..tab[4].."]"
248 if mapgen ~= "v6" then
249 -- No special treatment
252 -- Special treatment for v6 (add biome widgets)
254 -- Biome type (jungles, snowbiomes)
256 if flags.v6.snowbiomes == true then
258 elseif flags.v6.jungles == true then
265 form = form .. "label[0,"..(y+0.1)..";" .. fgettext("Biomes") .. "]"
268 form = form .. "dropdown[0,"..y..";6.3;mgv6_biomes;"
269 for b=1, #mgv6_biomes do
270 form = form .. mgv6_biomes[b][1]
271 if b < #mgv6_biomes then
275 form = form .. ";" .. biometype.. "]"
279 form = form .. "checkbox[0,"..y..";flag_mgv6_biomeblend;" ..
280 fgettext("Biome blending") .. ";"..strflag(flags.v6, "biomeblend").."]" ..
281 "tooltip[flag_mgv6_biomeblend;" ..
282 fgettext("Smooth transition between biomes") .. "]"
287 current_seed = core.formspec_escape(current_seed)
291 local str_flags, str_spflags
292 local label_flags, label_spflags = "", ""
294 str_flags, y = mg_main_flags(current_mg, y)
295 if str_flags ~= "" then
296 label_flags = "label[0,"..y_start..";" .. fgettext("Mapgen flags") .. "]"
302 str_spflags = mg_specific_flags(current_mg, y)
303 if str_spflags ~= "" then
304 label_spflags = "label[0,"..y_start..";" .. fgettext("Mapgen-specific flags") .. "]"
307 -- Warning if only devtest is installed
308 local devtest_only = ""
309 local gamelist_height = 2.3
310 if #pkgmgr.games == 1 and pkgmgr.games[1].id == "devtest" then
311 devtest_only = "box[0,0;5.8,1.7;#ff8800]" ..
312 "textarea[0.3,0;6,1.8;;;"..
313 fgettext("Warning: The Development Test is meant for developers.") .. "\n" ..
314 fgettext("Download a game, such as Minetest Game, from minetest.net") .. "]"
315 gamelist_height = 0.5
319 "size[12.25,7,true]" ..
323 "field[0.3,0.6;6,0.5;te_world_name;" ..
324 fgettext("World name") ..
325 ";" .. core.formspec_escape(worldname) .. "]" ..
327 "field[0.3,1.7;6,0.5;te_seed;" ..
329 ";".. current_seed .. "]" ..
331 "label[0,2;" .. fgettext("Mapgen") .. "]"..
332 "dropdown[0,2.5;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
334 "label[0,3.35;" .. fgettext("Game") .. "]"..
335 "textlist[0,3.85;5.8,"..gamelist_height..";games;" ..
336 pkgmgr.gamelist() .. ";" .. gameidx .. ";false]" ..
337 "container[0,4.5]" ..
344 label_flags .. str_flags ..
345 label_spflags .. str_spflags ..
349 "button[3.25,6.5;3,0.5;world_create_confirm;" .. fgettext("Create") .. "]" ..
350 "button[6.25,6.5;3,0.5;world_create_cancel;" .. fgettext("Cancel") .. "]"
356 local function create_world_buttonhandler(this, fields)
358 if fields["world_create_confirm"] or
359 fields["key_enter"] then
361 local worldname = fields["te_world_name"]
362 local gameindex = core.get_textlist_index("games")
364 if gameindex ~= nil then
365 if worldname == "" then
366 local random_number = math.random(10000, 99999)
367 local random_world_name = "Unnamed" .. random_number
368 worldname = random_world_name
371 core.settings:set("fixed_map_seed", fields["te_seed"])
374 if not menudata.worldlist:uid_exists_raw(worldname) then
375 core.settings:set("mg_name",fields["dd_mapgen"])
376 message = core.create_world(worldname,gameindex)
378 message = fgettext("A world named \"$1\" already exists", worldname)
381 if message ~= nil then
382 gamedata.errormessage = message
384 core.settings:set("menu_last_game",pkgmgr.games[gameindex].id)
385 if this.data.update_worldlist_filter then
386 menudata.worldlist:set_filtercriteria(pkgmgr.games[gameindex].id)
387 mm_texture.update("singleplayer", pkgmgr.games[gameindex].id)
389 menudata.worldlist:refresh()
390 core.settings:set("mainmenu_last_selected_world",
391 menudata.worldlist:raw_index_by_uid(worldname))
394 gamedata.errormessage = fgettext("No game selected")
400 worldname = fields.te_world_name
402 if fields["games"] then
403 local gameindex = core.get_textlist_index("games")
404 core.settings:set("menu_last_game", pkgmgr.games[gameindex].id)
408 for k,v in pairs(fields) do
409 local split = string.split(k, "_", nil, 3)
410 if split and split[1] == "flag" then
412 if split[2] == "mg" then
415 setting = split[2].."_spflags"
417 -- We replaced the underscore of flag names with a dash.
418 local flag = string.gsub(split[3], "-", "_")
419 local ftable = core.settings:get_flags(setting)
425 local flags = table_to_flags(ftable)
426 core.settings:set(setting, flags)
431 if fields["world_create_cancel"] then
436 if fields["mgv6_biomes"] then
437 local entry = minetest.formspec_escape(fields["mgv6_biomes"])
438 for b=1, #mgv6_biomes do
439 if entry == mgv6_biomes[b][1] then
440 local ftable = core.settings:get_flags("mgv6_spflags")
441 ftable.jungles = mgv6_biomes[b][2].jungles
442 ftable.snowbiomes = mgv6_biomes[b][2].snowbiomes
443 local flags = table_to_flags(ftable)
444 core.settings:set("mgv6_spflags", flags)
450 if fields["dd_mapgen"] then
451 core.settings:set("mg_name", fields["dd_mapgen"])
459 function create_create_world_dlg(update_worldlistfilter)
461 local retval = dialog_create("sp_create_world",
462 create_world_formspec,
463 create_world_buttonhandler,
465 retval.update_worldlist_filter = update_worldlistfilter