1 os.setlocale("C", "numeric")
3 local scriptpath = engine.get_scriptdir()
5 mt_color_grey = "#AAAAAA"
6 mt_color_blue = "#0000DD"
7 mt_color_green = "#00DD00"
8 mt_color_dark_green = "#003300"
10 dofile(scriptpath .. DIR_DELIM .. "filterlist.lua")
11 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
12 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
13 dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
20 --------------------------------------------------------------------------------
21 function render_favourite(spec,render_details)
24 if spec.name ~= nil then
25 text = text .. fs_escape_string(spec.name:trim())
27 -- if spec.description ~= nil and
28 -- fs_escape_string(spec.description):trim() ~= "" then
29 -- text = text .. " (" .. fs_escape_string(spec.description) .. ")"
32 if spec.address ~= nil then
33 text = text .. spec.address:trim()
37 if spec.port ~= nil and
38 spec.port ~= 30000 then
40 text = text .. ":" .. spec.port
43 if not render_details then
48 if spec.password == true then
49 details = details .. "*"
51 details = details .. "_"
55 details = details .. "C"
57 details = details .. "_"
61 details = details .. "D"
63 details = details .. "_"
67 details = details .. "P"
69 details = details .. "_"
71 details = details .. " "
73 return fs_escape_string(details) .. text
76 --------------------------------------------------------------------------------
77 os.tempfolder = function()
78 local filetocheck = os.tmpname()
79 os.remove(filetocheck)
81 local randname = "MTTempModFolder_" .. math.random(0,10000)
82 if DIR_DELIM == "\\" then
83 local tempfolder = os.getenv("TEMP")
84 return tempfolder .. filetocheck
86 local backstring = filetocheck:reverse()
87 return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
92 --------------------------------------------------------------------------------
93 function cleanup_path(temppath)
95 local parts = temppath:split("-")
98 if temppath ~= "" then
99 temppath = temppath .. "_"
101 temppath = temppath .. parts[i]
104 parts = temppath:split(".")
107 if temppath ~= "" then
108 temppath = temppath .. "_"
110 temppath = temppath .. parts[i]
113 parts = temppath:split("'")
116 if temppath ~= "" then
117 temppath = temppath .. ""
119 temppath = temppath .. parts[i]
122 parts = temppath:split(" ")
125 if temppath ~= "" then
128 temppath = temppath .. parts[i]
134 --------------------------------------------------------------------------------
136 function menu.set_texture(identifier,gamedetails)
137 local texture_set = false
138 if menu.texturepack ~= nil and gamedetails ~= nil then
139 local path = menu.basetexturedir ..
140 gamedetails.id .. "_menu_" .. identifier .. ".png"
142 if engine.set_background(identifier,path) then
147 if not texture_set and gamedetails ~= nil then
148 local path = gamedetails.path .. DIR_DELIM .."menu" ..
149 DIR_DELIM .. identifier .. ".png"
150 if engine.set_background(identifier,path) then
155 if not texture_set then
156 local path = menu.basetexturedir .. DIR_DELIM .."menu_" ..
158 if engine.set_background(identifier,path) then
163 if not texture_set then
164 local path = menu.defaulttexturedir .. DIR_DELIM .."menu_" ..
166 engine.set_background(identifier,path)
170 --------------------------------------------------------------------------------
171 function menu.update_gametype()
175 if (menu.game_last_check == nil or
176 menu.game_last_check ~= menu.last_game) and
177 tabbuilder.current_tab == "singleplayer" then
179 local gamedetails = menu.lastgame()
180 engine.set_topleft_text(gamedetails.name)
181 filterlist.set_filtercriteria(worldlist,gamedetails.id)
184 local background_set = false
185 if menu.texturepack ~= nil then
186 local path_background_texture = menu.basetexturedir ..
187 gamedetails.id .. "_menu_background.png"
189 if engine.set_background("background",path_background_texture) then
190 background_set = true
191 engine.set_clouds(false)
195 if not background_set then
196 local path_background_texture = gamedetails.path .. DIR_DELIM .."menu" ..
197 DIR_DELIM .. "background.png"
198 if engine.set_background("background",path_background_texture) then
199 background_set = true
200 engine.set_clouds(false)
204 if not background_set then
205 engine.set_clouds(true)
208 menu.set_texture("overlay",gamedetails)
209 menu.set_texture("header",gamedetails)
210 menu.set_texture("footer",gamedetails)
212 menu.game_last_check = menu.last_game
214 if menu.game_last_check ~= menu.last_game then
215 menu.game_last_check = menu.last_game
216 menu.reset_gametype()
221 --------------------------------------------------------------------------------
222 function menu.reset_gametype()
223 filterlist.set_filtercriteria(worldlist,nil)
224 menu.game_last_check = nil
226 local path_background_texture = menu.basetexturedir .. "menu_background.png"
228 if engine.set_background("background",path_background_texture) then
229 background_set = true
230 engine.set_clouds(false)
232 engine.set_clouds(true)
235 menu.set_texture("overlay",nil)
236 menu.set_texture("header",nil)
237 menu.set_texture("footer",nil)
238 engine.set_topleft_text("")
241 --------------------------------------------------------------------------------
242 function get_last_folder(text,count)
243 local parts = text:split(DIR_DELIM)
251 retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
257 --------------------------------------------------------------------------------
258 function init_globals()
260 gamedata.worldindex = 0
262 worldlist = filterlist.create(
265 function(element,uid)
266 if element.name == uid then
270 end, --unique id compare fct
271 function(element,gameid)
272 if element.gameid == gameid then
279 filterlist.add_sort_mechanism(worldlist,"alphabetic",sort_worlds_alphabetic)
280 filterlist.set_sortmode(worldlist,"alphabetic")
284 --------------------------------------------------------------------------------
285 function identify_filetype(name)
287 if name:sub(-3):lower() == "zip" then
294 if name:sub(-6):lower() == "tar.gz" or
295 name:sub(-3):lower() == "tgz"then
302 if name:sub(-6):lower() == "tar.bz2" then
309 if name:sub(-2):lower() == "7z" then
322 --------------------------------------------------------------------------------
323 function update_menu()
325 local formspec = "size[12,5.2]"
328 if gamedata.errormessage ~= nil then
329 formspec = formspec ..
330 "field[1,2;10,2;;ERROR: " ..
331 gamedata.errormessage ..
333 "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
335 formspec = formspec .. tabbuilder.gettab()
338 engine.update_formspec(formspec)
341 --------------------------------------------------------------------------------
342 function menu.render_world_list()
345 local current_worldlist = filterlist.get_list(worldlist)
347 for i,v in ipairs(current_worldlist) do
349 retval = retval ..","
352 retval = retval .. v.name ..
353 " \\[" .. v.gameid .. "\\]"
359 --------------------------------------------------------------------------------
362 gamemgr.update_gamelist()
364 menu.last_game = tonumber(engine.setting_get("main_menu_last_game_idx"))
366 if type(menu.last_game) ~= "number" then
370 if engine.setting_getbool("public_serverlist") then
371 menu.favorites = engine.get_favorites("online")
373 menu.favorites = engine.get_favorites("local")
377 menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
378 DIR_DELIM .. "textures" .. DIR_DELIM .. "base" ..
379 DIR_DELIM .. "pack" .. DIR_DELIM
380 menu.basetexturedir = menu.defaulttexturedir
382 menu.texturepack = engine.setting_get("texture_path")
384 if menu.texturepack ~= nil then
385 menu.basetexturedir = menu.texturepack .. DIR_DELIM
389 --------------------------------------------------------------------------------
390 function menu.lastgame()
391 if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
392 return gamemgr.games[menu.last_game]
395 if #gamemgr.games >= 1 then
397 return gamemgr.games[menu.last_game]
404 --------------------------------------------------------------------------------
405 function menu.update_last_game()
407 local current_world = filterlist.get_raw_element(worldlist,
408 engine.setting_get("mainmenu_last_selected_world")
411 if current_world == nil then
415 for i=1,#gamemgr.games,1 do
416 if gamemgr.games[i].id == current_world.gameid then
418 engine.setting_set("main_menu_last_game_idx",menu.last_game)
424 --------------------------------------------------------------------------------
425 function menu.handle_key_up_down(fields,textlist,settingname)
427 if fields["key_up"] then
428 local oldidx = engine.get_textlist_index(textlist)
431 local newidx = oldidx -1
432 engine.setting_set(settingname,
433 filterlist.get_raw_index(worldlist,newidx))
437 if fields["key_down"] then
438 local oldidx = engine.get_textlist_index(textlist)
440 if oldidx < filterlist.size(worldlist) then
441 local newidx = oldidx + 1
442 engine.setting_set(settingname,
443 filterlist.get_raw_index(worldlist,newidx))
449 --------------------------------------------------------------------------------
450 function menubar.handle_buttons(fields)
451 for i=1,#menubar.buttons,1 do
452 if fields[menubar.buttons[i].btn_name] ~= nil then
453 menu.last_game = menubar.buttons[i].index
454 engine.setting_set("main_menu_last_game_idx",menu.last_game)
455 menu.update_gametype()
460 --------------------------------------------------------------------------------
461 function menubar.refresh()
462 menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
463 "box[-0.3,5.6;12.4,0.05;FFFFFF]"
466 local button_base = -0.25
468 local maxbuttons = #gamemgr.games
470 if maxbuttons > 10 then
474 for i=1,maxbuttons,1 do
476 local btn_name = "menubar_btn_" .. gamemgr.games[i].id
477 local buttonpos = button_base + (i-1) * 1.245
478 if gamemgr.games[i].menuicon_path ~= nil and
479 gamemgr.games[i].menuicon_path ~= "" then
481 menubar.formspec = menubar.formspec ..
482 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;" ..
483 gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
486 local part1 = gamemgr.games[i].id:sub(1,5)
487 local part2 = gamemgr.games[i].id:sub(6,10)
488 local part3 = gamemgr.games[i].id:sub(11)
490 local text = part1 .. "\n" .. part2
493 text = text .. "\n" .. part3
495 menubar.formspec = menubar.formspec ..
496 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;;" ..btn_name ..
497 ";" .. text .. ";true;true]"
505 table.insert(menubar.buttons,toadd)
509 --------------------------------------------------------------------------------
510 function tabbuilder.dialog_create_world()
511 local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
513 local current_mg = engine.setting_get("mg_name")
518 for k,v in pairs(mapgens) do
519 if current_mg == v then
523 mglist = mglist .. v .. ","
525 mglist = mglist:sub(1, -2)
528 "label[2,0;World name]"..
529 "label[2,1;Mapgen]"..
530 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
532 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
533 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
534 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
535 "textlist[4.2,1.9;5.8,2.3;games;" ..
536 gamemgr.gamelist() ..
537 ";" .. menu.last_game .. ";true]"
542 --------------------------------------------------------------------------------
543 function tabbuilder.dialog_delete_world()
544 return "label[2,2;Delete World \"" .. filterlist.get_raw_list(worldlist)[menu.world_to_del].name .. "\"?]"..
545 "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
546 "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
549 --------------------------------------------------------------------------------
550 function tabbuilder.gettab()
553 if tabbuilder.show_buttons then
554 retval = retval .. tabbuilder.tab_header()
557 if tabbuilder.current_tab == "singleplayer" then
558 retval = retval .. tabbuilder.tab_singleplayer()
561 if tabbuilder.current_tab == "multiplayer" then
562 retval = retval .. tabbuilder.tab_multiplayer()
565 if tabbuilder.current_tab == "server" then
566 retval = retval .. tabbuilder.tab_server()
569 if tabbuilder.current_tab == "settings" then
570 retval = retval .. tabbuilder.tab_settings()
573 if tabbuilder.current_tab == "credits" then
574 retval = retval .. tabbuilder.tab_credits()
577 if tabbuilder.current_tab == "dialog_create_world" then
578 retval = retval .. tabbuilder.dialog_create_world()
581 if tabbuilder.current_tab == "dialog_delete_world" then
582 retval = retval .. tabbuilder.dialog_delete_world()
585 retval = retval .. modmgr.gettab(tabbuilder.current_tab)
586 retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
587 retval = retval .. modstore.gettab(tabbuilder.current_tab)
592 --------------------------------------------------------------------------------
593 function tabbuilder.handle_create_world_buttons(fields)
595 if fields["world_create_confirm"] or
596 fields["key_enter"] then
598 local worldname = fields["te_world_name"]
599 local gameindex = engine.get_textlist_index("games")
606 if not filterlist.uid_exists(worldlist,worldname) then
607 engine.setting_set("mg_name",fields["dd_mapgen"])
608 message = engine.create_world(worldname,gameindex)
610 message = "A world named \"" .. worldname .. "\" already exists"
613 if message ~= nil then
614 gamedata.errormessage = message
616 menu.last_game = gameindex
617 engine.setting_set("main_menu_last_game_idx",gameindex)
619 filterlist.refresh(worldlist)
620 engine.setting_set("mainmenu_last_selected_world",
621 filterlist.raw_index_by_uid(worldlist,worldname))
624 gamedata.errormessage = "No worldname given or no game selected"
628 if fields["games"] then
629 tabbuilder.skipformupdate = true
634 tabbuilder.is_dialog = false
635 tabbuilder.show_buttons = true
636 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
639 --------------------------------------------------------------------------------
640 function tabbuilder.handle_delete_world_buttons(fields)
642 if fields["world_delete_confirm"] then
643 if menu.world_to_del > 0 and
644 menu.world_to_del <= #filterlist.get_raw_list(worldlist) then
645 engine.delete_world(menu.world_to_del)
646 menu.world_to_del = 0
647 filterlist.refresh(worldlist)
651 tabbuilder.is_dialog = false
652 tabbuilder.show_buttons = true
653 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
656 --------------------------------------------------------------------------------
657 function tabbuilder.handle_multiplayer_buttons(fields)
659 if fields["te_name"] ~= nil then
660 gamedata.playername = fields["te_name"]
661 engine.setting_set("name", fields["te_name"])
664 if fields["favourites"] ~= nil then
665 local event = explode_textlist_event(fields["favourites"])
666 if event.typ == "DCL" then
667 gamedata.address = menu.favorites[event.index].address
668 gamedata.port = menu.favorites[event.index].port
669 gamedata.playername = fields["te_name"]
670 if fields["te_pwd"] ~= nil then
671 gamedata.password = fields["te_pwd"]
673 gamedata.selected_world = 0
675 if menu.favorites ~= nil then
676 gamedata.servername = menu.favorites[event.index].name
677 gamedata.serverdescription = menu.favorites[event.index].description
680 if gamedata.address ~= nil and
681 gamedata.port ~= nil then
687 if event.typ == "CHG" then
688 local address = menu.favorites[event.index].address
689 local port = menu.favorites[event.index].port
691 if address ~= nil and
693 engine.setting_set("address",address)
694 engine.setting_set("port",port)
697 menu.fav_selected = event.index
702 if fields["key_up"] ~= nil or
703 fields["key_down"] ~= nil then
705 local fav_idx = engine.get_textlist_index("favourites")
707 if fields["key_up"] ~= nil and fav_idx > 1 then
709 else if fields["key_down"] and fav_idx < #menu.favorites then
713 local address = menu.favorites[fav_idx].address
714 local port = menu.favorites[fav_idx].port
716 if address ~= nil and
718 engine.setting_set("address",address)
719 engine.setting_set("port",port)
722 menu.fav_selected = fav_idx
726 if fields["cb_public_serverlist"] ~= nil then
727 engine.setting_setbool("public_serverlist",
728 tabbuilder.tobool(fields["cb_public_serverlist"]))
730 if engine.setting_getbool("public_serverlist") then
731 menu.favorites = engine.get_favorites("online")
733 menu.favorites = engine.get_favorites("local")
735 menu.fav_selected = nil
739 if fields["btn_delete_favorite"] ~= nil then
740 local current_favourite = engine.get_textlist_index("favourites")
741 engine.delete_favorite(current_favourite)
742 menu.favorites = engine.get_favorites()
743 menu.fav_selected = nil
745 engine.setting_set("address","")
746 engine.setting_get("port","")
751 if fields["btn_mp_connect"] ~= nil or
752 fields["key_enter"] then
754 gamedata.playername = fields["te_name"]
755 gamedata.password = fields["te_pwd"]
756 gamedata.address = fields["te_address"]
757 gamedata.port = fields["te_port"]
759 local fav_idx = engine.get_textlist_index("favourites")
761 if fav_idx > 0 and fav_idx <= #menu.favorites and
762 menu.favorites[fav_idx].address == fields["te_address"] and
763 menu.favorites[fav_idx].port == fields["te_port"] then
765 gamedata.servername = menu.favorites[fav_idx].name
766 gamedata.serverdescription = menu.favorites[fav_idx].description
768 gamedata.servername = ""
769 gamedata.serverdescription = ""
772 gamedata.selected_world = 0
779 --------------------------------------------------------------------------------
780 function tabbuilder.handle_server_buttons(fields)
782 local world_doubleclick = false
784 if fields["srv_worlds"] ~= nil then
785 local event = explode_textlist_event(fields["srv_worlds"])
787 if event.typ == "DCL" then
788 world_doubleclick = true
790 if event.typ == "CHG" then
791 engine.setting_set("mainmenu_last_selected_world",
792 filterlist.get_raw_index(worldlist,engine.get_textlist_index("srv_worlds")))
796 menu.handle_key_up_down(fields,"srv_worlds","mainmenu_last_selected_world")
798 if fields["cb_creative_mode"] then
799 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
802 if fields["cb_enable_damage"] then
803 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
806 if fields["cb_server_announce"] then
807 engine.setting_setbool("server_announce",tabbuilder.tobool(fields["cb_server_announce"]))
810 if fields["start_server"] ~= nil or
812 fields["key_enter"] then
813 local selected = engine.get_textlist_index("srv_worlds")
815 gamedata.playername = fields["te_playername"]
816 gamedata.password = fields["te_passwd"]
817 gamedata.port = fields["te_serverport"]
818 gamedata.address = ""
819 gamedata.selected_world = filterlist.get_raw_index(worldlist,selected)
821 menu.update_last_game(gamedata.selected_world)
826 if fields["world_create"] ~= nil then
827 tabbuilder.current_tab = "dialog_create_world"
828 tabbuilder.is_dialog = true
829 tabbuilder.show_buttons = false
832 if fields["world_delete"] ~= nil then
833 local selected = engine.get_textlist_index("srv_worlds")
835 selected <= filterlist.size(worldlist) then
836 local world = filterlist.get_list(worldlist)[selected]
838 world.name ~= nil and
839 world.name ~= "" then
840 menu.world_to_del = filterlist.get_raw_index(worldlist,selected)
841 tabbuilder.current_tab = "dialog_delete_world"
842 tabbuilder.is_dialog = true
843 tabbuilder.show_buttons = false
845 menu.world_to_del = 0
850 if fields["world_configure"] ~= nil then
851 selected = engine.get_textlist_index("srv_worlds")
853 modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected)
854 if modmgr.init_worldconfig() then
855 tabbuilder.current_tab = "dialog_configure_world"
856 tabbuilder.is_dialog = true
857 tabbuilder.show_buttons = false
863 --------------------------------------------------------------------------------
864 function tabbuilder.tobool(text)
865 if text == "true" then
872 --------------------------------------------------------------------------------
873 function tabbuilder.handle_settings_buttons(fields)
874 if fields["cb_fancy_trees"] then
875 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
878 if fields["cb_smooth_lighting"] then
879 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
881 if fields["cb_3d_clouds"] then
882 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
884 if fields["cb_opaque_water"] then
885 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
888 if fields["cb_mipmapping"] then
889 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
891 if fields["cb_anisotrophic"] then
892 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
894 if fields["cb_bilinear"] then
895 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
897 if fields["cb_trilinear"] then
898 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
901 if fields["cb_shaders"] then
902 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
904 if fields["cb_pre_ivis"] then
905 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
907 if fields["cb_particles"] then
908 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
910 if fields["cb_finite_liquid"] then
911 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
914 if fields["btn_change_keys"] ~= nil then
915 engine.show_keys_menu()
919 --------------------------------------------------------------------------------
920 function tabbuilder.handle_singleplayer_buttons(fields)
922 local world_doubleclick = false
924 if fields["sp_worlds"] ~= nil then
925 local event = explode_textlist_event(fields["sp_worlds"])
927 if event.typ == "DCL" then
928 world_doubleclick = true
931 if event.typ == "CHG" then
932 engine.setting_set("mainmenu_last_selected_world",
933 filterlist.get_raw_index(worldlist,engine.get_textlist_index("sp_worlds")))
937 menu.handle_key_up_down(fields,"sp_worlds","mainmenu_last_selected_world")
939 if fields["cb_creative_mode"] then
940 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
943 if fields["cb_enable_damage"] then
944 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
947 if fields["play"] ~= nil or
949 fields["key_enter"] then
950 local selected = engine.get_textlist_index("sp_worlds")
952 gamedata.selected_world = filterlist.get_raw_index(worldlist,selected)
953 gamedata.singleplayer = true
955 menu.update_last_game(gamedata.selected_world)
961 if fields["world_create"] ~= nil then
962 tabbuilder.current_tab = "dialog_create_world"
963 tabbuilder.is_dialog = true
964 tabbuilder.show_buttons = false
967 if fields["world_delete"] ~= nil then
968 local selected = engine.get_textlist_index("sp_worlds")
970 selected <= filterlist.size(worldlist) then
971 local world = filterlist.get_list(worldlist)[selected]
973 world.name ~= nil and
974 world.name ~= "" then
975 menu.world_to_del = filterlist.get_raw_index(worldlist,selected)
976 tabbuilder.current_tab = "dialog_delete_world"
977 tabbuilder.is_dialog = true
978 tabbuilder.show_buttons = false
980 menu.world_to_del = 0
985 if fields["world_configure"] ~= nil then
986 selected = engine.get_textlist_index("sp_worlds")
988 modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected)
989 if modmgr.init_worldconfig() then
990 tabbuilder.current_tab = "dialog_configure_world"
991 tabbuilder.is_dialog = true
992 tabbuilder.show_buttons = false
998 --------------------------------------------------------------------------------
999 function tabbuilder.tab_header()
1001 if tabbuilder.last_tab_index == nil then
1002 tabbuilder.last_tab_index = 1
1007 for i=1,#tabbuilder.current_buttons,1 do
1010 toadd = toadd .. ","
1013 toadd = toadd .. tabbuilder.current_buttons[i].caption
1015 return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
1018 --------------------------------------------------------------------------------
1019 function tabbuilder.handle_tab_buttons(fields)
1021 if fields["main_tab"] then
1022 local index = tonumber(fields["main_tab"])
1023 tabbuilder.last_tab_index = index
1024 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
1026 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1029 --handle tab changes
1030 if tabbuilder.current_tab ~= tabbuilder.old_tab then
1031 if tabbuilder.current_tab ~= "singleplayer" then
1032 menu.reset_gametype()
1036 if tabbuilder.current_tab == "singleplayer" then
1037 menu.update_gametype()
1040 tabbuilder.old_tab = tabbuilder.current_tab
1043 --------------------------------------------------------------------------------
1044 function tabbuilder.init()
1045 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1047 if tabbuilder.current_tab == nil or
1048 tabbuilder.current_tab == "" then
1049 tabbuilder.current_tab = "singleplayer"
1050 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1054 --initialize tab buttons
1055 tabbuilder.last_tab = nil
1056 tabbuilder.show_buttons = true
1058 tabbuilder.current_buttons = {}
1059 table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
1060 table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
1061 table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
1062 table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
1064 if engine.setting_getbool("main_menu_game_mgr") then
1065 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
1068 if engine.setting_getbool("main_menu_mod_mgr") then
1069 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
1071 table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
1074 for i=1,#tabbuilder.current_buttons,1 do
1075 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
1076 tabbuilder.last_tab_index = i
1080 menu.update_gametype()
1083 --------------------------------------------------------------------------------
1084 function tabbuilder.tab_multiplayer()
1087 "vertlabel[0,-0.25;CLIENT]" ..
1088 "label[1,-0.25;Favorites:]"..
1089 "label[1,4.25;Address/Port]"..
1090 "label[9,2.75;Name/Password]" ..
1091 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
1092 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
1093 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
1094 dump(engine.setting_getbool("public_serverlist")) .. "]"
1096 if not engine.setting_getbool("public_serverlist") then
1098 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]"
1102 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
1103 "field[9.3,3.75;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
1104 "pwdfield[9.3,4.5;2.5,0.5;te_pwd;]" ..
1105 "textarea[9.3,0.25;2.5,2.75;;"
1106 if menu.fav_selected ~= nil and
1107 menu.favorites[menu.fav_selected].description ~= nil then
1109 fs_escape_string(menu.favorites[menu.fav_selected].description,true)
1114 "textlist[1,0.35;7.5,3.35;favourites;"
1116 local render_details = engine.setting_getbool("public_serverlist")
1118 if #menu.favorites > 0 then
1119 retval = retval .. render_favourite(menu.favorites[1],render_details)
1121 for i=2,#menu.favorites,1 do
1122 retval = retval .. "," .. render_favourite(menu.favorites[i],render_details)
1126 if menu.fav_selected ~= nil then
1127 retval = retval .. ";" .. menu.fav_selected .. "]"
1129 retval = retval .. ";0]"
1135 --------------------------------------------------------------------------------
1136 function tabbuilder.tab_server()
1138 local index = filterlist.get_current_index(worldlist,
1139 tonumber(engine.setting_get("mainmenu_last_selected_world"))
1143 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1144 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1145 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1146 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
1147 "label[4,-0.25;Select World:]"..
1148 "vertlabel[0,-0.25;START SERVER]" ..
1149 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1150 dump(engine.setting_getbool("creative_mode")) .. "]"..
1151 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1152 dump(engine.setting_getbool("enable_damage")) .. "]"..
1153 "checkbox[0.5,1.15;cb_server_announce;Public;" ..
1154 dump(engine.setting_getbool("server_announce")) .. "]"..
1155 "field[0.8,3.2;3,0.5;te_playername;Name;" ..
1156 engine.setting_get("name") .. "]" ..
1157 "pwdfield[0.8,4.2;3,0.5;te_passwd;Password]" ..
1158 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
1159 "textlist[4,0.25;7.5,3.7;srv_worlds;" ..
1160 menu.render_world_list() ..
1166 --------------------------------------------------------------------------------
1167 function tabbuilder.tab_settings()
1168 return "vertlabel[0,0;SETTINGS]" ..
1169 "checkbox[1,0.75;cb_fancy_trees;Fancy trees;" .. dump(engine.setting_getbool("new_style_leaves")) .. "]"..
1170 "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
1171 "checkbox[1,1.75;cb_3d_clouds;3D Clouds;" .. dump(engine.setting_getbool("enable_3d_clouds")) .. "]"..
1172 "checkbox[1,2.25;cb_opaque_water;Opaque Water;" .. dump(engine.setting_getbool("opaque_water")) .. "]"..
1174 "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;" .. dump(engine.setting_getbool("mip_map")) .. "]"..
1175 "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter")) .. "]"..
1176 "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;" .. dump(engine.setting_getbool("bilinear_filter")) .. "]"..
1177 "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;" .. dump(engine.setting_getbool("trilinear_filter")) .. "]"..
1179 "checkbox[7.5,0.75;cb_shaders;Shaders;" .. dump(engine.setting_getbool("enable_shaders")) .. "]"..
1180 "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals")) .. "]"..
1181 "checkbox[7.5,1.75;cb_particles;Enable Particles;" .. dump(engine.setting_getbool("enable_particles")) .. "]"..
1182 "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;" .. dump(engine.setting_getbool("liquid_finite")) .. "]"..
1184 "button[1,3.75;2.25,0.5;btn_change_keys;Change keys]"
1187 --------------------------------------------------------------------------------
1188 function tabbuilder.tab_singleplayer()
1190 local index = filterlist.get_current_index(worldlist,
1191 tonumber(engine.setting_get("mainmenu_last_selected_world"))
1194 return "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1195 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1196 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1197 "button[8.5,4.95;3.25,0.5;play;Play]" ..
1198 "label[4,-0.25;Select World:]"..
1199 "vertlabel[0,-0.25;SINGLE PLAYER]" ..
1200 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1201 dump(engine.setting_getbool("creative_mode")) .. "]"..
1202 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1203 dump(engine.setting_getbool("enable_damage")) .. "]"..
1204 "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
1205 menu.render_world_list() ..
1206 ";" .. index .. "]" ..
1210 --------------------------------------------------------------------------------
1211 function tabbuilder.tab_credits()
1212 return "vertlabel[0,-0.5;CREDITS]" ..
1213 "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
1214 "label[0.5,3.3;http://minetest.net]" ..
1215 "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
1216 "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
1217 "#FFFF00Core Developers," ..
1218 "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
1219 "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
1220 "PilzAdam <pilzadam@minetest.net>," ..
1221 "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
1222 "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
1223 "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
1224 "proller <proler@gmail.com>,"..
1225 "sfan5 <sfan5@live.de>,"..
1226 "kahrl <kahrl@gmx.net>,"..
1228 "#FFFF00Active Contributors," ..
1230 "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
1231 "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
1232 "Jeija <jeija@mesecons.net>,"..
1233 "MirceaKitsune <mirceakitsune@gmail.com>,"..
1235 "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
1236 "0gb.us <0gb.us@0gb.us>,"..
1238 "#FFFF00Previous Contributors," ..
1239 "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
1240 "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
1241 "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
1242 "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
1243 "matttpt <matttpt@gmail.com>,"..
1244 "JacobF <queatz@gmail.com>,"..
1248 --------------------------------------------------------------------------------
1249 function tabbuilder.checkretval(retval)
1251 if retval ~= nil then
1252 if retval.current_tab ~= nil then
1253 tabbuilder.current_tab = retval.current_tab
1256 if retval.is_dialog ~= nil then
1257 tabbuilder.is_dialog = retval.is_dialog
1260 if retval.show_buttons ~= nil then
1261 tabbuilder.show_buttons = retval.show_buttons
1264 if retval.skipformupdate ~= nil then
1265 tabbuilder.skipformupdate = retval.skipformupdate
1270 --------------------------------------------------------------------------------
1271 --------------------------------------------------------------------------------
1272 -- initialize callbacks
1273 --------------------------------------------------------------------------------
1274 --------------------------------------------------------------------------------
1275 engine.button_handler = function(fields)
1276 --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1278 if fields["btn_error_confirm"] then
1279 gamedata.errormessage = nil
1282 local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1283 tabbuilder.checkretval(retval)
1285 retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1286 tabbuilder.checkretval(retval)
1288 retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1289 tabbuilder.checkretval(retval)
1291 if tabbuilder.current_tab == "dialog_create_world" then
1292 tabbuilder.handle_create_world_buttons(fields)
1295 if tabbuilder.current_tab == "dialog_delete_world" then
1296 tabbuilder.handle_delete_world_buttons(fields)
1299 if tabbuilder.current_tab == "singleplayer" then
1300 tabbuilder.handle_singleplayer_buttons(fields)
1303 if tabbuilder.current_tab == "multiplayer" then
1304 tabbuilder.handle_multiplayer_buttons(fields)
1307 if tabbuilder.current_tab == "settings" then
1308 tabbuilder.handle_settings_buttons(fields)
1311 if tabbuilder.current_tab == "server" then
1312 tabbuilder.handle_server_buttons(fields)
1316 tabbuilder.handle_tab_buttons(fields)
1319 menubar.handle_buttons(fields)
1321 if not tabbuilder.skipformupdate then
1325 tabbuilder.skipformupdate = false
1329 --------------------------------------------------------------------------------
1330 engine.event_handler = function(event)
1331 if event == "MenuQuit" then
1332 if tabbuilder.is_dialog then
1333 tabbuilder.is_dialog = false
1334 tabbuilder.show_buttons = true
1335 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1336 menu.update_gametype()
1344 --------------------------------------------------------------------------------
1345 --------------------------------------------------------------------------------
1347 --------------------------------------------------------------------------------
1348 --------------------------------------------------------------------------------