1 os.setlocale("C", "numeric")
3 local scriptpath = engine.get_scriptdir()
5 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
6 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
7 dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
13 --------------------------------------------------------------------------------
14 function render_favourite(spec)
17 if spec.name ~= nil then
18 text = text .. spec.name:trim()
20 if spec.description ~= nil then
21 --TODO make sure there's no invalid chat in spec.description
22 text = text .. " (" .. fs_escape_string(spec.description) .. ")"
25 if spec.address ~= nil then
26 text = text .. spec.address:trim()
31 if spec.password == true then
38 details = details .. "C"
40 details = details .. " "
44 details = details .. "D"
46 details = details .. " "
50 details = details .. "P"
52 details = details .. " "
55 if spec.port ~= nil then
56 text = text .. ":" .. spec.port:trim()
64 --------------------------------------------------------------------------------
65 os.tempfolder = function()
66 local filetocheck = os.tmpname()
67 os.remove(filetocheck)
69 local randname = "MTTempModFolder_" .. math.random(0,10000)
70 if DIR_DELIM == "\\" then
71 local tempfolder = os.getenv("TEMP")
72 return tempfolder .. filetocheck
74 local backstring = filetocheck:reverse()
75 return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
80 --------------------------------------------------------------------------------
81 function cleanup_path(temppath)
83 local parts = temppath:split("-")
86 if temppath ~= "" then
87 temppath = temppath .. "_"
89 temppath = temppath .. parts[i]
92 parts = temppath:split(".")
95 if temppath ~= "" then
96 temppath = temppath .. "_"
98 temppath = temppath .. parts[i]
101 parts = temppath:split("'")
104 if temppath ~= "" then
105 temppath = temppath .. ""
107 temppath = temppath .. parts[i]
110 parts = temppath:split(" ")
113 if temppath ~= "" then
116 temppath = temppath .. parts[i]
122 function menu.set_texture(identifier,gamedetails)
123 local texture_set = false
124 if menu.texturepack ~= nil then
125 local path = menu.basetexturedir ..
126 gamedetails.id .. "_menu_" .. identifier .. ".png"
128 if engine.set_background(identifier,path) then
133 if not texture_set then
134 local path = gamedetails.path .. DIR_DELIM .."menu" ..
135 DIR_DELIM .. identifier .. ".png"
136 if engine.set_background(identifier,path) then
141 if not texture_set then
142 local path = menu.basetexturedir .. DIR_DELIM .."menu_" ..
144 if engine.set_background(identifier,path) then
149 if not texture_set then
150 local path = menu.defaulttexturedir .. DIR_DELIM .."menu_" ..
152 engine.set_background(identifier,path)
156 --------------------------------------------------------------------------------
157 function menu.update_gametype()
158 if (menu.game_last_check == nil or
159 menu.game_last_check ~= menu.last_game) and
160 tabbuilder.current_tab == "singleplayer" then
162 local gamedetails = menu.lastgame()
163 engine.set_topleft_text(gamedetails.name)
166 local background_set = false
167 if menu.texturepack ~= nil then
168 local path_background_texture = menu.basetexturedir ..
169 gamedetails.id .. "_menu_background.png"
171 if engine.set_background("background",path_background_texture) then
172 background_set = true
173 engine.set_clouds(false)
177 if not background_set then
178 local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" ..
179 DIR_DELIM .. "background.png"
180 if engine.set_background("background",path_background_texture) then
181 background_set = true
182 engine.set_clouds(false)
186 if not background_set then
187 engine.set_clouds(true)
190 menu.set_texture("overlay",gamedetails)
191 menu.set_texture("header",gamedetails)
192 menu.set_texture("footer",gamedetails)
194 menu.game_last_check = menu.last_game
196 if menu.game_last_check ~= menu.last_game then
197 menu.game_last_check = menu.last_game
198 menu.reset_gametype()
203 --------------------------------------------------------------------------------
204 function menu.reset_gametype()
205 menu.game_last_check = nil
206 engine.set_clouds(true)
207 engine.set_background("background","")
208 engine.set_background("overlay",menu.basetexturedir .. "menu_overlay.png")
209 engine.set_background("header",menu.basetexturedir .. "menu_header.png")
210 engine.set_background("footer",menu.basetexturedir .. "menu_footer.png")
211 engine.set_topleft_text("")
214 --------------------------------------------------------------------------------
215 function get_last_folder(text,count)
216 local parts = text:split(DIR_DELIM)
224 retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
230 --------------------------------------------------------------------------------
231 function init_globals()
233 gamedata.worldindex = 0
236 --------------------------------------------------------------------------------
237 function identify_filetype(name)
239 if name:sub(-3):lower() == "zip" then
246 if name:sub(-6):lower() == "tar.gz" or
247 name:sub(-3):lower() == "tgz"then
254 if name:sub(-6):lower() == "tar.bz2" then
261 if name:sub(-2):lower() == "7z" then
274 --------------------------------------------------------------------------------
275 function update_menu()
277 local formspec = "size[12,5.2]"
280 if gamedata.errormessage ~= nil then
281 formspec = formspec ..
282 "field[1,2;10,2;;ERROR: " ..
283 gamedata.errormessage ..
285 "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
287 formspec = formspec .. tabbuilder.gettab()
290 engine.update_formspec(formspec)
293 --------------------------------------------------------------------------------
294 function menu.filtered_game_list()
297 local current_game = menu.lastgame()
299 for i=1,#menu.worldlist,1 do
300 if menu.worldlist[i].gameid == current_game.id then
302 retval = retval ..","
305 retval = retval .. menu.worldlist[i].name ..
306 " \\[" .. menu.worldlist[i].gameid .. "\\]"
313 --------------------------------------------------------------------------------
314 function menu.filtered_game_list_raw()
317 local current_game = menu.lastgame()
319 for i=1,#menu.worldlist,1 do
320 if menu.worldlist[i].gameid == current_game.id then
321 table.insert(retval,menu.worldlist[i])
328 --------------------------------------------------------------------------------
329 function menu.filtered_index_to_plain(filtered_index)
331 local current_game = menu.lastgame()
335 if menu.worldlist == nil then
339 for i=1,#menu.worldlist,1 do
340 if menu.worldlist[i].gameid == current_game.id then
341 temp_idx = temp_idx +1
344 if temp_idx == filtered_index then
351 --------------------------------------------------------------------------------
354 gamemgr.update_gamelist()
356 menu.worldlist = engine.get_worlds()
358 menu.last_world = tonumber(engine.setting_get("main_menu_last_world_idx"))
359 menu.last_game = tonumber(engine.setting_get("main_menu_last_game_idx"))
361 if type(menu.last_world) ~= "number" then
365 if type(menu.last_game) ~= "number" then
369 if engine.setting_getbool("public_serverlist") then
370 menu.favorites = engine.get_favorites("online")
372 menu.favorites = engine.get_favorites("local")
376 menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
377 DIR_DELIM .. "textures" .. DIR_DELIM .. "base" ..
378 DIR_DELIM .. "pack" .. DIR_DELIM
379 menu.basetexturedir = menu.defaulttexturedir
381 menu.texturepack = engine.setting_get("texture_path")
383 if menu.texturepack ~= nil then
384 menu.basetexturedir = menu.texturepack .. DIR_DELIM
388 --------------------------------------------------------------------------------
389 function menu.lastgame()
390 if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
391 return gamemgr.games[menu.last_game]
394 if #gamemgr.games >= 1 then
396 return gamemgr.games[menu.last_game]
403 --------------------------------------------------------------------------------
404 function menu.lastworld()
405 if menu.last_world ~= nil and
406 menu.last_world > 0 and
407 menu.last_world <= #menu.worldlist then
408 return menu.worldlist[menu.last_world]
411 if #menu.worldlist >= 1 then
413 return menu.worldlist[menu.last_world]
420 --------------------------------------------------------------------------------
421 function menu.update_last_game(world_idx)
422 if gamedata.selected_world <= #menu.worldlist then
423 local world = menu.worldlist[gamedata.selected_world]
429 for i=1,#gamemgr.games,1 do
430 if gamemgr.games[i].id == world.gameid then
432 engine.setting_set("main_menu_last_game_idx",menu.last_game)
439 --------------------------------------------------------------------------------
440 function menubar.handle_buttons(fields)
441 for i=1,#menubar.buttons,1 do
442 if fields[menubar.buttons[i].btn_name] ~= nil then
443 menu.last_game = menubar.buttons[i].index
444 engine.setting_set("main_menu_last_game_idx",menu.last_game)
445 menu.update_gametype()
450 --------------------------------------------------------------------------------
451 function menubar.refresh()
452 menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
453 "box[-0.3,5.6;12.4,0.05;FFFFFF]"
456 local button_base = -0.25
458 local maxbuttons = #gamemgr.games
460 if maxbuttons > 10 then
464 for i=1,maxbuttons,1 do
466 local btn_name = "menubar_btn_" .. gamemgr.games[i].id
467 local buttonpos = button_base + (i-1) * 1.245
468 if gamemgr.games[i].menuicon_path ~= nil and
469 gamemgr.games[i].menuicon_path ~= "" then
471 menubar.formspec = menubar.formspec ..
472 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;" ..
473 gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
476 local part1 = gamemgr.games[i].id:sub(1,5)
477 local part2 = gamemgr.games[i].id:sub(6,10)
478 local part3 = gamemgr.games[i].id:sub(11)
480 local text = part1 .. "\n" .. part2
483 text = text .. "\n" .. part3
485 menubar.formspec = menubar.formspec ..
486 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;;" ..btn_name ..
487 ";" .. text .. ";true;true]"
495 table.insert(menubar.buttons,toadd)
499 --------------------------------------------------------------------------------
500 function tabbuilder.dialog_create_world()
501 local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
503 local current_mg = engine.setting_get("mg_name")
508 for k,v in pairs(mapgens) do
509 if current_mg == v then
513 mglist = mglist .. v .. ","
515 mglist = mglist:sub(1, -2)
518 "label[2,0;World name]"..
519 "label[2,1;Mapgen]"..
520 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
522 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
523 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
524 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
525 "textlist[4.2,1.9;5.8,2.3;games;" ..
526 gamemgr.gamelist() ..
527 ";" .. menu.last_game .. ";true]"
532 --------------------------------------------------------------------------------
533 function tabbuilder.dialog_delete_world()
534 return "label[2,2;Delete World \"" .. menu.lastworld().name .. "\"?]"..
535 "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
536 "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
539 --------------------------------------------------------------------------------
540 function tabbuilder.gettab()
543 if tabbuilder.show_buttons then
544 retval = retval .. tabbuilder.tab_header()
547 if tabbuilder.current_tab == "singleplayer" then
548 retval = retval .. tabbuilder.tab_singleplayer()
551 if tabbuilder.current_tab == "multiplayer" then
552 retval = retval .. tabbuilder.tab_multiplayer()
555 if tabbuilder.current_tab == "server" then
556 retval = retval .. tabbuilder.tab_server()
559 if tabbuilder.current_tab == "settings" then
560 retval = retval .. tabbuilder.tab_settings()
563 if tabbuilder.current_tab == "credits" then
564 retval = retval .. tabbuilder.tab_credits()
567 if tabbuilder.current_tab == "dialog_create_world" then
568 retval = retval .. tabbuilder.dialog_create_world()
571 if tabbuilder.current_tab == "dialog_delete_world" then
572 retval = retval .. tabbuilder.dialog_delete_world()
575 retval = retval .. modmgr.gettab(tabbuilder.current_tab)
576 retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
577 retval = retval .. modstore.gettab(tabbuilder.current_tab)
582 --------------------------------------------------------------------------------
583 function tabbuilder.handle_create_world_buttons(fields)
585 if fields["world_create_confirm"] or
586 fields["key_enter"] then
588 local worldname = fields["te_world_name"]
589 local gameindex = engine.get_textlist_index("games")
593 menu.worldlist = engine.get_worlds()
596 for i=1,#menu.worldlist,1 do
597 if menu.worldlist[i].name == worldname then
606 engine.setting_set("mg_name",fields["dd_mapgen"])
607 message = engine.create_world(worldname,gameindex)
609 message = "A world named \"" .. worldname .. "\" already exists"
612 if message ~= nil then
613 gamedata.errormessage = message
615 menu.last_game = gameindex
616 engine.setting_set("main_menu_last_game_idx",gameindex)
617 menu.worldlist = engine.get_worlds()
619 local worldlist = menu.worldlist
621 if tabbuilder.current_tab == "singleplayer" then
622 worldlist = menu.filtered_game_list_raw()
627 for i=1,#worldlist,1 do
628 if worldlist[i].name == worldname then
634 engine.setting_set("main_menu_singleplayer_world_idx", index)
635 menu.last_world = index
638 gamedata.errormessage = "No worldname given or no game selected"
642 if fields["games"] then
643 tabbuilder.skipformupdate = true
647 tabbuilder.is_dialog = false
648 tabbuilder.show_buttons = true
649 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
652 --------------------------------------------------------------------------------
653 function tabbuilder.handle_delete_world_buttons(fields)
655 if fields["world_delete_confirm"] then
656 if menu.last_world > 0 and
657 menu.last_world <= #menu.worldlist then
658 engine.delete_world(menu.last_world)
659 menu.worldlist = engine.get_worlds()
664 tabbuilder.is_dialog = false
665 tabbuilder.show_buttons = true
666 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
669 --------------------------------------------------------------------------------
670 function tabbuilder.handle_multiplayer_buttons(fields)
672 if fields["te_name"] ~= nil then
673 gamedata.playername = fields["te_name"]
674 engine.setting_set("name", fields["te_name"])
677 if fields["favourites"] ~= nil then
678 local event = explode_textlist_event(fields["favourites"])
679 if event.typ == "DCL" then
680 --gamedata.address = menu.favorites[event.index].name
681 if gamedata.address == nil then
682 gamedata.address = menu.favorites[event.index].address
684 gamedata.port = menu.favorites[event.index].port
685 gamedata.playername = fields["te_name"]
686 if fields["te_pwd"] ~= nil then
687 gamedata.password = fields["te_pwd"]
689 gamedata.selected_world = 0
691 if gamedata.address ~= nil and
692 gamedata.port ~= nil then
698 if event.typ == "CHG" then
699 local address = menu.favorites[event.index].name
700 if address == nil then
701 address = menu.favorites[event.index].address
703 local port = menu.favorites[event.index].port
705 if address ~= nil and
707 engine.setting_set("address",address)
708 engine.setting_set("port",port)
711 menu.fav_selected = event.index
716 if fields["key_up"] ~= nil or
717 fields["key_down"] ~= nil then
719 local fav_idx = engine.get_textlist_index("favourites")
721 if fields["key_up"] ~= nil and fav_idx > 1 then
723 else if fields["key_down"] and fav_idx < #menu.favorites then
727 local address = menu.favorites[fav_idx].name
728 if address == nil then
729 address = menu.favorites[fav_idx].address
731 local port = menu.favorites[fav_idx].port
733 if address ~= nil and
735 engine.setting_set("address",address)
736 engine.setting_set("port",port)
739 menu.fav_selected = fav_idx
743 if fields["cb_public_serverlist"] ~= nil then
744 engine.setting_setbool("public_serverlist",
745 tabbuilder.tobool(fields["cb_public_serverlist"]))
747 if engine.setting_getbool("public_serverlist") then
748 menu.favorites = engine.get_favorites("online")
750 menu.favorites = engine.get_favorites("local")
756 if fields["btn_delete_favorite"] ~= nil then
757 local current_favourite = engine.get_textlist_index("favourites")
758 engine.delete_favorite(current_favourite)
759 menu.favorites = engine.get_favorites()
761 engine.setting_set("address","")
762 engine.setting_get("port","")
767 if fields["btn_mp_connect"] ~= nil or
768 fields["key_enter"] then
770 gamedata.playername = fields["te_name"]
771 gamedata.password = fields["te_pwd"]
772 gamedata.address = fields["te_address"]
773 gamedata.port = fields["te_port"]
774 gamedata.selected_world = 0
781 --------------------------------------------------------------------------------
782 function tabbuilder.handle_server_buttons(fields)
784 local world_doubleclick = false
786 if fields["srv_worlds"] ~= nil then
787 local event = explode_textlist_event(fields["srv_worlds"])
789 if event.typ == "DCL" then
790 world_doubleclick = true
792 if event.typ == "CHG" then
793 engine.setting_set("main_menu_last_world_idx",engine.get_textlist_index("srv_worlds"))
797 if fields["key_up"] then
798 local oldidx = engine.get_textlist_index("srv_worlds")
801 local newidx = oldidx -1
802 engine.setting_set("main_menu_last_world_idx",newidx)
806 if fields["key_down"] then
807 local oldidx = engine.get_textlist_index("srv_worlds")
809 if oldidx < #menu.worldlist then
810 local newidx = oldidx + 1
811 engine.setting_set("main_menu_last_world_idx",newidx)
815 if fields["cb_creative_mode"] then
816 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
819 if fields["cb_enable_damage"] then
820 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
824 if fields["start_server"] ~= nil or
826 fields["key_enter"] then
827 local selected = engine.get_textlist_index("srv_worlds")
830 gamedata.playername = fields["te_playername"]
831 gamedata.password = fields["te_passwd"]
832 gamedata.port = fields["te_serverport"]
833 gamedata.address = ""
834 gamedata.selected_world = selected
836 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
837 engine.setting_set("main_menu_last_world_idx",gamedata.selected_world)
839 menu.update_last_game(gamedata.selected_world)
844 if fields["world_create"] ~= nil then
845 tabbuilder.current_tab = "dialog_create_world"
846 tabbuilder.is_dialog = true
847 tabbuilder.show_buttons = false
850 if fields["world_delete"] ~= nil then
851 local selected = engine.get_textlist_index("srv_worlds")
853 menu.last_world = engine.get_textlist_index("srv_worlds")
854 if menu.lastworld() ~= nil and
855 menu.lastworld().name ~= nil and
856 menu.lastworld().name ~= "" then
857 tabbuilder.current_tab = "dialog_delete_world"
858 tabbuilder.is_dialog = true
859 tabbuilder.show_buttons = false
866 if fields["world_configure"] ~= nil then
867 selected = engine.get_textlist_index("srv_worlds")
869 modmgr.world_config_selected_world = selected
870 if modmgr.init_worldconfig() then
871 tabbuilder.current_tab = "dialog_configure_world"
872 tabbuilder.is_dialog = true
873 tabbuilder.show_buttons = false
879 --------------------------------------------------------------------------------
880 function tabbuilder.tobool(text)
881 if text == "true" then
888 --------------------------------------------------------------------------------
889 function tabbuilder.handle_settings_buttons(fields)
890 if fields["cb_fancy_trees"] then
891 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
894 if fields["cb_smooth_lighting"] then
895 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
897 if fields["cb_3d_clouds"] then
898 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
900 if fields["cb_opaque_water"] then
901 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
904 if fields["cb_mipmapping"] then
905 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
907 if fields["cb_anisotrophic"] then
908 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
910 if fields["cb_bilinear"] then
911 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
913 if fields["cb_trilinear"] then
914 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
917 if fields["cb_shaders"] then
918 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
920 if fields["cb_pre_ivis"] then
921 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
923 if fields["cb_particles"] then
924 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
926 if fields["cb_finite_liquid"] then
927 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
930 if fields["btn_change_keys"] ~= nil then
931 engine.show_keys_menu()
935 --------------------------------------------------------------------------------
936 function tabbuilder.handle_singleplayer_buttons(fields)
938 local world_doubleclick = false
940 if fields["sp_worlds"] ~= nil then
941 local event = explode_textlist_event(fields["sp_worlds"])
943 if event.typ == "DCL" then
944 world_doubleclick = true
947 if event.typ == "CHG" then
948 engine.setting_set("main_menu_singleplayer_world_idx",engine.get_textlist_index("sp_worlds"))
952 if fields["key_up"] then
953 local oldidx = engine.get_textlist_index("sp_worlds")
956 local newidx = oldidx -1
957 engine.setting_set("main_menu_singleplayer_world_idx",newidx)
961 if fields["key_down"] then
962 local oldidx = engine.get_textlist_index("sp_worlds")
964 if oldidx < #menu.filtered_game_list_raw() then
965 local newidx = oldidx + 1
966 engine.setting_set("main_menu_singleplayer_world_idx",newidx)
970 if fields["cb_creative_mode"] then
971 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
974 if fields["cb_enable_damage"] then
975 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
978 if fields["play"] ~= nil or
980 fields["key_enter"] then
981 local selected = engine.get_textlist_index("sp_worlds")
983 gamedata.selected_world = menu.filtered_index_to_plain(selected)
984 gamedata.singleplayer = true
986 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
987 engine.setting_set("main_menu_singleplayer_world_idx",selected)
989 menu.update_last_game(gamedata.selected_world)
995 if fields["world_create"] ~= nil then
996 tabbuilder.current_tab = "dialog_create_world"
997 tabbuilder.is_dialog = true
998 tabbuilder.show_buttons = false
1001 if fields["world_delete"] ~= nil then
1002 local selected = engine.get_textlist_index("sp_worlds")
1003 if selected > 0 then
1004 menu.last_world = menu.filtered_index_to_plain(selected)
1005 if menu.lastworld() ~= nil and
1006 menu.lastworld().name ~= nil and
1007 menu.lastworld().name ~= "" then
1008 tabbuilder.current_tab = "dialog_delete_world"
1009 tabbuilder.is_dialog = true
1010 tabbuilder.show_buttons = false
1017 if fields["world_configure"] ~= nil then
1018 selected = engine.get_textlist_index("sp_worlds")
1019 if selected > 0 then
1020 modmgr.world_config_selected_world = menu.filtered_index_to_plain(selected)
1021 if modmgr.init_worldconfig() then
1022 tabbuilder.current_tab = "dialog_configure_world"
1023 tabbuilder.is_dialog = true
1024 tabbuilder.show_buttons = false
1030 --------------------------------------------------------------------------------
1031 function tabbuilder.tab_header()
1033 if tabbuilder.last_tab_index == nil then
1034 tabbuilder.last_tab_index = 1
1039 for i=1,#tabbuilder.current_buttons,1 do
1042 toadd = toadd .. ","
1045 toadd = toadd .. tabbuilder.current_buttons[i].caption
1047 return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
1050 --------------------------------------------------------------------------------
1051 function tabbuilder.handle_tab_buttons(fields)
1053 if fields["main_tab"] then
1054 local index = tonumber(fields["main_tab"])
1055 tabbuilder.last_tab_index = index
1056 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
1058 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1061 --handle tab changes
1062 if tabbuilder.current_tab ~= tabbuilder.old_tab then
1063 if tabbuilder.current_tab ~= "singleplayer" then
1064 menu.reset_gametype()
1068 if tabbuilder.current_tab == "singleplayer" then
1069 menu.update_gametype()
1072 tabbuilder.old_tab = tabbuilder.current_tab
1075 --------------------------------------------------------------------------------
1076 function tabbuilder.init()
1077 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1079 if tabbuilder.current_tab == nil or
1080 tabbuilder.current_tab == "" then
1081 tabbuilder.current_tab = "singleplayer"
1082 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1086 --initialize tab buttons
1087 tabbuilder.last_tab = nil
1088 tabbuilder.show_buttons = true
1090 tabbuilder.current_buttons = {}
1091 table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
1092 table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
1093 table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
1094 table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
1096 if engine.setting_getbool("main_menu_game_mgr") then
1097 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
1100 if engine.setting_getbool("main_menu_mod_mgr") then
1101 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
1103 table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
1106 for i=1,#tabbuilder.current_buttons,1 do
1107 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
1108 tabbuilder.last_tab_index = i
1112 menu.update_gametype()
1115 --------------------------------------------------------------------------------
1116 function tabbuilder.tab_multiplayer()
1119 "vertlabel[0,-0.25;CLIENT]" ..
1120 "label[1,-0.25;Favorites:]"..
1121 "label[1,4.25;Address/Port]"..
1122 "label[9,0;Name/Password]" ..
1123 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
1124 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
1125 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]" ..
1126 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
1127 "field[9.25,1;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
1128 "pwdfield[9.25,1.75;2.5,0.5;te_pwd;]" ..
1129 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
1130 dump(engine.setting_getbool("public_serverlist")) .. "]" ..
1131 "textlist[1,0.35;7.5,3.35;favourites;"
1133 if #menu.favorites > 0 then
1134 retval = retval .. render_favourite(menu.favorites[1])
1136 for i=2,#menu.favorites,1 do
1137 retval = retval .. "," .. render_favourite(menu.favorites[i])
1141 print("cfav: " .. dump(menu.fav_selected))
1142 if menu.fav_selected ~= nil then
1143 retval = retval .. ";" .. menu.fav_selected .. "]"
1145 retval = retval .. ";0]"
1151 --------------------------------------------------------------------------------
1152 function tabbuilder.tab_server()
1153 local index = engine.setting_get("main_menu_last_world_idx")
1155 if index == nil then
1160 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1161 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1162 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1163 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
1164 "label[4,-0.25;Select World:]"..
1165 "vertlabel[0,-0.25;START SERVER]" ..
1166 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1167 dump(engine.setting_getbool("creative_mode")) .. "]"..
1168 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1169 dump(engine.setting_getbool("enable_damage")) .. "]"..
1170 "field[0.8,2.2;3,0.5;te_playername;Name;" ..
1171 engine.setting_get("name") .. "]" ..
1172 "pwdfield[0.8,3.2;3,0.5;te_passwd;Password]" ..
1173 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
1174 "textlist[4,0.25;7.5,3.7;srv_worlds;"
1176 if #menu.worldlist > 0 then
1177 retval = retval .. menu.worldlist[1].name ..
1178 " \\[" .. menu.worldlist[1].gameid .. "\\]"
1180 for i=2,#menu.worldlist,1 do
1181 retval = retval .. "," .. menu.worldlist[i].name ..
1182 " \\[" .. menu.worldlist[i].gameid .. "\\]"
1186 retval = retval .. ";" .. index .. "]"
1191 --------------------------------------------------------------------------------
1192 function tabbuilder.tab_settings()
1193 return "vertlabel[0,0;SETTINGS]" ..
1194 "checkbox[1,0.75;cb_fancy_trees;Fancy trees;" .. dump(engine.setting_getbool("new_style_leaves")) .. "]"..
1195 "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
1196 "checkbox[1,1.75;cb_3d_clouds;3D Clouds;" .. dump(engine.setting_getbool("enable_3d_clouds")) .. "]"..
1197 "checkbox[1,2.25;cb_opaque_water;Opaque Water;" .. dump(engine.setting_getbool("opaque_water")) .. "]"..
1199 "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;" .. dump(engine.setting_getbool("mip_map")) .. "]"..
1200 "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter")) .. "]"..
1201 "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;" .. dump(engine.setting_getbool("bilinear_filter")) .. "]"..
1202 "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;" .. dump(engine.setting_getbool("trilinear_filter")) .. "]"..
1204 "checkbox[7.5,0.75;cb_shaders;Shaders;" .. dump(engine.setting_getbool("enable_shaders")) .. "]"..
1205 "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals")) .. "]"..
1206 "checkbox[7.5,1.75;cb_particles;Enable Particles;" .. dump(engine.setting_getbool("enable_particles")) .. "]"..
1207 "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;" .. dump(engine.setting_getbool("liquid_finite")) .. "]"..
1209 "button[1,3.75;2.25,0.5;btn_change_keys;Change keys]"
1212 --------------------------------------------------------------------------------
1213 function tabbuilder.tab_singleplayer()
1214 local index = engine.setting_get("main_menu_singleplayer_world_idx")
1216 if index == nil then
1220 return "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1221 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1222 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1223 "button[8.5,4.95;3.25,0.5;play;Play]" ..
1224 "label[4,-0.25;Select World:]"..
1225 "vertlabel[0,-0.25;SINGLE PLAYER]" ..
1226 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1227 dump(engine.setting_getbool("creative_mode")) .. "]"..
1228 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1229 dump(engine.setting_getbool("enable_damage")) .. "]"..
1230 "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
1231 menu.filtered_game_list() ..
1232 ";" .. index .. "]" ..
1236 --------------------------------------------------------------------------------
1237 function tabbuilder.tab_credits()
1238 return "vertlabel[0,-0.5;CREDITS]" ..
1239 "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
1240 "label[0.5,3.3;http://minetest.net]" ..
1241 "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
1242 "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
1243 "#FFFF00Core Developers," ..
1244 "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
1245 "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
1246 "PilzAdam <pilzadam@minetest.net>," ..
1247 "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
1248 "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
1249 "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
1250 "proller <proler@gmail.com>,"..
1251 "sfan5 <sfan5@live.de>,"..
1252 "kahrl <kahrl@gmx.net>,"..
1254 "#FFFF00Active Contributors," ..
1256 "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
1257 "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
1258 "Jeija <jeija@mesecons.net>,"..
1259 "MirceaKitsune <mirceakitsune@gmail.com>,"..
1261 "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
1262 "0gb.us <0gb.us@0gb.us>,"..
1264 "#FFFF00Previous Contributors," ..
1265 "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
1266 "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
1267 "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
1268 "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
1269 "matttpt <matttpt@gmail.com>,"..
1270 "JacobF <queatz@gmail.com>,"..
1274 --------------------------------------------------------------------------------
1275 function tabbuilder.checkretval(retval)
1277 if retval ~= nil then
1278 if retval.current_tab ~= nil then
1279 tabbuilder.current_tab = retval.current_tab
1282 if retval.is_dialog ~= nil then
1283 tabbuilder.is_dialog = retval.is_dialog
1286 if retval.show_buttons ~= nil then
1287 tabbuilder.show_buttons = retval.show_buttons
1290 if retval.skipformupdate ~= nil then
1291 tabbuilder.skipformupdate = retval.skipformupdate
1296 --------------------------------------------------------------------------------
1297 --------------------------------------------------------------------------------
1298 -- initialize callbacks
1299 --------------------------------------------------------------------------------
1300 --------------------------------------------------------------------------------
1301 engine.button_handler = function(fields)
1302 --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1304 if fields["btn_error_confirm"] then
1305 gamedata.errormessage = nil
1308 local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1309 tabbuilder.checkretval(retval)
1311 retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1312 tabbuilder.checkretval(retval)
1314 retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1315 tabbuilder.checkretval(retval)
1317 if tabbuilder.current_tab == "dialog_create_world" then
1318 tabbuilder.handle_create_world_buttons(fields)
1321 if tabbuilder.current_tab == "dialog_delete_world" then
1322 tabbuilder.handle_delete_world_buttons(fields)
1325 if tabbuilder.current_tab == "singleplayer" then
1326 tabbuilder.handle_singleplayer_buttons(fields)
1329 if tabbuilder.current_tab == "multiplayer" then
1330 tabbuilder.handle_multiplayer_buttons(fields)
1333 if tabbuilder.current_tab == "settings" then
1334 tabbuilder.handle_settings_buttons(fields)
1337 if tabbuilder.current_tab == "server" then
1338 tabbuilder.handle_server_buttons(fields)
1342 tabbuilder.handle_tab_buttons(fields)
1345 menubar.handle_buttons(fields)
1347 if not tabbuilder.skipformupdate then
1351 tabbuilder.skipformupdate = false
1355 --------------------------------------------------------------------------------
1356 engine.event_handler = function(event)
1357 if event == "MenuQuit" then
1358 if tabbuilder.is_dialog then
1359 tabbuilder.is_dialog = false
1360 tabbuilder.show_buttons = true
1361 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1369 --------------------------------------------------------------------------------
1370 --------------------------------------------------------------------------------
1372 --------------------------------------------------------------------------------
1373 --------------------------------------------------------------------------------