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 and gamedetails ~= 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 and gamedetails ~= nil 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
207 local path_background_texture = menu.basetexturedir .. "menu_background.png"
209 if engine.set_background("background",path_background_texture) then
210 background_set = true
211 engine.set_clouds(false)
213 engine.set_clouds(true)
216 menu.set_texture("overlay",nil)
217 menu.set_texture("header",nil)
218 menu.set_texture("footer",nil)
219 engine.set_topleft_text("")
222 --------------------------------------------------------------------------------
223 function get_last_folder(text,count)
224 local parts = text:split(DIR_DELIM)
232 retval = retval .. parts[#parts - (count-i)] .. DIR_DELIM
238 --------------------------------------------------------------------------------
239 function init_globals()
241 gamedata.worldindex = 0
244 --------------------------------------------------------------------------------
245 function identify_filetype(name)
247 if name:sub(-3):lower() == "zip" then
254 if name:sub(-6):lower() == "tar.gz" or
255 name:sub(-3):lower() == "tgz"then
262 if name:sub(-6):lower() == "tar.bz2" then
269 if name:sub(-2):lower() == "7z" then
282 --------------------------------------------------------------------------------
283 function update_menu()
285 local formspec = "size[12,5.2]"
288 if gamedata.errormessage ~= nil then
289 formspec = formspec ..
290 "field[1,2;10,2;;ERROR: " ..
291 gamedata.errormessage ..
293 "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
295 formspec = formspec .. tabbuilder.gettab()
298 engine.update_formspec(formspec)
301 --------------------------------------------------------------------------------
302 function menu.filtered_game_list()
305 local current_game = menu.lastgame()
307 for i=1,#menu.worldlist,1 do
308 if menu.worldlist[i].gameid == current_game.id then
310 retval = retval ..","
313 retval = retval .. menu.worldlist[i].name ..
314 " \\[" .. menu.worldlist[i].gameid .. "\\]"
321 --------------------------------------------------------------------------------
322 function menu.filtered_game_list_raw()
325 local current_game = menu.lastgame()
327 for i=1,#menu.worldlist,1 do
328 if menu.worldlist[i].gameid == current_game.id then
329 table.insert(retval,menu.worldlist[i])
336 --------------------------------------------------------------------------------
337 function menu.filtered_index_to_plain(filtered_index)
339 local current_game = menu.lastgame()
343 if menu.worldlist == nil then
347 for i=1,#menu.worldlist,1 do
348 if menu.worldlist[i].gameid == current_game.id then
349 temp_idx = temp_idx +1
352 if temp_idx == filtered_index then
359 --------------------------------------------------------------------------------
362 gamemgr.update_gamelist()
364 menu.worldlist = engine.get_worlds()
366 menu.last_world = tonumber(engine.setting_get("main_menu_last_world_idx"))
367 menu.last_game = tonumber(engine.setting_get("main_menu_last_game_idx"))
369 if type(menu.last_world) ~= "number" then
373 if type(menu.last_game) ~= "number" then
377 if engine.setting_getbool("public_serverlist") then
378 menu.favorites = engine.get_favorites("online")
380 menu.favorites = engine.get_favorites("local")
384 menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
385 DIR_DELIM .. "textures" .. DIR_DELIM .. "base" ..
386 DIR_DELIM .. "pack" .. DIR_DELIM
387 menu.basetexturedir = menu.defaulttexturedir
389 menu.texturepack = engine.setting_get("texture_path")
391 if menu.texturepack ~= nil then
392 menu.basetexturedir = menu.texturepack .. DIR_DELIM
396 --------------------------------------------------------------------------------
397 function menu.lastgame()
398 if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
399 return gamemgr.games[menu.last_game]
402 if #gamemgr.games >= 1 then
404 return gamemgr.games[menu.last_game]
411 --------------------------------------------------------------------------------
412 function menu.lastworld()
413 if menu.last_world ~= nil and
414 menu.last_world > 0 and
415 menu.last_world <= #menu.worldlist then
416 return menu.worldlist[menu.last_world]
419 if #menu.worldlist >= 1 then
421 return menu.worldlist[menu.last_world]
428 --------------------------------------------------------------------------------
429 function menu.update_last_game(world_idx)
430 if gamedata.selected_world <= #menu.worldlist then
431 local world = menu.worldlist[gamedata.selected_world]
437 for i=1,#gamemgr.games,1 do
438 if gamemgr.games[i].id == world.gameid then
440 engine.setting_set("main_menu_last_game_idx",menu.last_game)
447 --------------------------------------------------------------------------------
448 function menubar.handle_buttons(fields)
449 for i=1,#menubar.buttons,1 do
450 if fields[menubar.buttons[i].btn_name] ~= nil then
451 menu.last_game = menubar.buttons[i].index
452 engine.setting_set("main_menu_last_game_idx",menu.last_game)
453 menu.update_gametype()
458 --------------------------------------------------------------------------------
459 function menubar.refresh()
460 menubar.formspec = "box[-0.3,5.625;12.4,1.3;000000]" ..
461 "box[-0.3,5.6;12.4,0.05;FFFFFF]"
464 local button_base = -0.25
466 local maxbuttons = #gamemgr.games
468 if maxbuttons > 10 then
472 for i=1,maxbuttons,1 do
474 local btn_name = "menubar_btn_" .. gamemgr.games[i].id
475 local buttonpos = button_base + (i-1) * 1.245
476 if gamemgr.games[i].menuicon_path ~= nil and
477 gamemgr.games[i].menuicon_path ~= "" then
479 menubar.formspec = menubar.formspec ..
480 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;" ..
481 gamemgr.games[i].menuicon_path .. ";" .. btn_name .. ";;true;false]"
484 local part1 = gamemgr.games[i].id:sub(1,5)
485 local part2 = gamemgr.games[i].id:sub(6,10)
486 local part3 = gamemgr.games[i].id:sub(11)
488 local text = part1 .. "\n" .. part2
491 text = text .. "\n" .. part3
493 menubar.formspec = menubar.formspec ..
494 "image_button[" .. buttonpos .. ",5.7;1.3,1.3;;" ..btn_name ..
495 ";" .. text .. ";true;true]"
503 table.insert(menubar.buttons,toadd)
507 --------------------------------------------------------------------------------
508 function tabbuilder.dialog_create_world()
509 local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
511 local current_mg = engine.setting_get("mg_name")
516 for k,v in pairs(mapgens) do
517 if current_mg == v then
521 mglist = mglist .. v .. ","
523 mglist = mglist:sub(1, -2)
526 "label[2,0;World name]"..
527 "label[2,1;Mapgen]"..
528 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
530 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
531 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
532 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
533 "textlist[4.2,1.9;5.8,2.3;games;" ..
534 gamemgr.gamelist() ..
535 ";" .. menu.last_game .. ";true]"
540 --------------------------------------------------------------------------------
541 function tabbuilder.dialog_delete_world()
542 return "label[2,2;Delete World \"" .. menu.lastworld().name .. "\"?]"..
543 "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
544 "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
547 --------------------------------------------------------------------------------
548 function tabbuilder.gettab()
551 if tabbuilder.show_buttons then
552 retval = retval .. tabbuilder.tab_header()
555 if tabbuilder.current_tab == "singleplayer" then
556 retval = retval .. tabbuilder.tab_singleplayer()
559 if tabbuilder.current_tab == "multiplayer" then
560 retval = retval .. tabbuilder.tab_multiplayer()
563 if tabbuilder.current_tab == "server" then
564 retval = retval .. tabbuilder.tab_server()
567 if tabbuilder.current_tab == "settings" then
568 retval = retval .. tabbuilder.tab_settings()
571 if tabbuilder.current_tab == "credits" then
572 retval = retval .. tabbuilder.tab_credits()
575 if tabbuilder.current_tab == "dialog_create_world" then
576 retval = retval .. tabbuilder.dialog_create_world()
579 if tabbuilder.current_tab == "dialog_delete_world" then
580 retval = retval .. tabbuilder.dialog_delete_world()
583 retval = retval .. modmgr.gettab(tabbuilder.current_tab)
584 retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
585 retval = retval .. modstore.gettab(tabbuilder.current_tab)
590 --------------------------------------------------------------------------------
591 function tabbuilder.handle_create_world_buttons(fields)
593 if fields["world_create_confirm"] or
594 fields["key_enter"] then
596 local worldname = fields["te_world_name"]
597 local gameindex = engine.get_textlist_index("games")
601 menu.worldlist = engine.get_worlds()
604 for i=1,#menu.worldlist,1 do
605 if menu.worldlist[i].name == worldname then
614 engine.setting_set("mg_name",fields["dd_mapgen"])
615 message = engine.create_world(worldname,gameindex)
617 message = "A world named \"" .. worldname .. "\" already exists"
620 if message ~= nil then
621 gamedata.errormessage = message
623 menu.last_game = gameindex
624 engine.setting_set("main_menu_last_game_idx",gameindex)
625 menu.worldlist = engine.get_worlds()
627 local worldlist = menu.worldlist
629 if tabbuilder.current_tab == "singleplayer" then
630 worldlist = menu.filtered_game_list_raw()
635 for i=1,#worldlist,1 do
636 if worldlist[i].name == worldname then
642 engine.setting_set("main_menu_singleplayer_world_idx", index)
643 menu.last_world = index
646 gamedata.errormessage = "No worldname given or no game selected"
650 if fields["games"] then
651 tabbuilder.skipformupdate = true
655 tabbuilder.is_dialog = false
656 tabbuilder.show_buttons = true
657 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
660 --------------------------------------------------------------------------------
661 function tabbuilder.handle_delete_world_buttons(fields)
663 if fields["world_delete_confirm"] then
664 if menu.last_world > 0 and
665 menu.last_world <= #menu.worldlist then
666 engine.delete_world(menu.last_world)
667 menu.worldlist = engine.get_worlds()
672 tabbuilder.is_dialog = false
673 tabbuilder.show_buttons = true
674 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
677 --------------------------------------------------------------------------------
678 function tabbuilder.handle_multiplayer_buttons(fields)
680 if fields["te_name"] ~= nil then
681 gamedata.playername = fields["te_name"]
682 engine.setting_set("name", fields["te_name"])
685 if fields["favourites"] ~= nil then
686 local event = explode_textlist_event(fields["favourites"])
687 if event.typ == "DCL" then
688 --gamedata.address = menu.favorites[event.index].name
689 if gamedata.address == nil then
690 gamedata.address = menu.favorites[event.index].address
692 gamedata.port = menu.favorites[event.index].port
693 gamedata.playername = fields["te_name"]
694 if fields["te_pwd"] ~= nil then
695 gamedata.password = fields["te_pwd"]
697 gamedata.selected_world = 0
699 if gamedata.address ~= nil and
700 gamedata.port ~= nil then
706 if event.typ == "CHG" then
707 local address = menu.favorites[event.index].name
708 if address == nil then
709 address = menu.favorites[event.index].address
711 local port = menu.favorites[event.index].port
713 if address ~= nil and
715 engine.setting_set("address",address)
716 engine.setting_set("port",port)
719 menu.fav_selected = event.index
724 if fields["key_up"] ~= nil or
725 fields["key_down"] ~= nil then
727 local fav_idx = engine.get_textlist_index("favourites")
729 if fields["key_up"] ~= nil and fav_idx > 1 then
731 else if fields["key_down"] and fav_idx < #menu.favorites then
735 local address = menu.favorites[fav_idx].name
736 if address == nil then
737 address = menu.favorites[fav_idx].address
739 local port = menu.favorites[fav_idx].port
741 if address ~= nil and
743 engine.setting_set("address",address)
744 engine.setting_set("port",port)
747 menu.fav_selected = fav_idx
751 if fields["cb_public_serverlist"] ~= nil then
752 engine.setting_setbool("public_serverlist",
753 tabbuilder.tobool(fields["cb_public_serverlist"]))
755 if engine.setting_getbool("public_serverlist") then
756 menu.favorites = engine.get_favorites("online")
758 menu.favorites = engine.get_favorites("local")
764 if fields["btn_delete_favorite"] ~= nil then
765 local current_favourite = engine.get_textlist_index("favourites")
766 engine.delete_favorite(current_favourite)
767 menu.favorites = engine.get_favorites()
769 engine.setting_set("address","")
770 engine.setting_get("port","")
775 if fields["btn_mp_connect"] ~= nil or
776 fields["key_enter"] then
778 gamedata.playername = fields["te_name"]
779 gamedata.password = fields["te_pwd"]
780 gamedata.address = fields["te_address"]
781 gamedata.port = fields["te_port"]
782 gamedata.selected_world = 0
789 --------------------------------------------------------------------------------
790 function tabbuilder.handle_server_buttons(fields)
792 local world_doubleclick = false
794 if fields["srv_worlds"] ~= nil then
795 local event = explode_textlist_event(fields["srv_worlds"])
797 if event.typ == "DCL" then
798 world_doubleclick = true
800 if event.typ == "CHG" then
801 engine.setting_set("main_menu_last_world_idx",engine.get_textlist_index("srv_worlds"))
805 if fields["key_up"] then
806 local oldidx = engine.get_textlist_index("srv_worlds")
809 local newidx = oldidx -1
810 engine.setting_set("main_menu_last_world_idx",newidx)
814 if fields["key_down"] then
815 local oldidx = engine.get_textlist_index("srv_worlds")
817 if oldidx < #menu.worldlist then
818 local newidx = oldidx + 1
819 engine.setting_set("main_menu_last_world_idx",newidx)
823 if fields["cb_creative_mode"] then
824 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
827 if fields["cb_enable_damage"] then
828 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
831 if fields["cb_server_announce"] then
832 engine.setting_setbool("server_announce",tabbuilder.tobool(fields["cb_server_announce"]))
836 if fields["start_server"] ~= nil or
838 fields["key_enter"] then
839 local selected = engine.get_textlist_index("srv_worlds")
842 gamedata.playername = fields["te_playername"]
843 gamedata.password = fields["te_passwd"]
844 gamedata.port = fields["te_serverport"]
845 gamedata.address = ""
846 gamedata.selected_world = selected
848 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
849 engine.setting_set("main_menu_last_world_idx",gamedata.selected_world)
851 menu.update_last_game(gamedata.selected_world)
856 if fields["world_create"] ~= nil then
857 tabbuilder.current_tab = "dialog_create_world"
858 tabbuilder.is_dialog = true
859 tabbuilder.show_buttons = false
862 if fields["world_delete"] ~= nil then
863 local selected = engine.get_textlist_index("srv_worlds")
865 menu.last_world = engine.get_textlist_index("srv_worlds")
866 if menu.lastworld() ~= nil and
867 menu.lastworld().name ~= nil and
868 menu.lastworld().name ~= "" then
869 tabbuilder.current_tab = "dialog_delete_world"
870 tabbuilder.is_dialog = true
871 tabbuilder.show_buttons = false
878 if fields["world_configure"] ~= nil then
879 selected = engine.get_textlist_index("srv_worlds")
881 modmgr.world_config_selected_world = selected
882 if modmgr.init_worldconfig() then
883 tabbuilder.current_tab = "dialog_configure_world"
884 tabbuilder.is_dialog = true
885 tabbuilder.show_buttons = false
891 --------------------------------------------------------------------------------
892 function tabbuilder.tobool(text)
893 if text == "true" then
900 --------------------------------------------------------------------------------
901 function tabbuilder.handle_settings_buttons(fields)
902 if fields["cb_fancy_trees"] then
903 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
906 if fields["cb_smooth_lighting"] then
907 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
909 if fields["cb_3d_clouds"] then
910 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
912 if fields["cb_opaque_water"] then
913 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
916 if fields["cb_mipmapping"] then
917 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
919 if fields["cb_anisotrophic"] then
920 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
922 if fields["cb_bilinear"] then
923 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
925 if fields["cb_trilinear"] then
926 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
929 if fields["cb_shaders"] then
930 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
932 if fields["cb_pre_ivis"] then
933 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
935 if fields["cb_particles"] then
936 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
938 if fields["cb_finite_liquid"] then
939 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
942 if fields["btn_change_keys"] ~= nil then
943 engine.show_keys_menu()
947 --------------------------------------------------------------------------------
948 function tabbuilder.handle_singleplayer_buttons(fields)
950 local world_doubleclick = false
952 if fields["sp_worlds"] ~= nil then
953 local event = explode_textlist_event(fields["sp_worlds"])
955 if event.typ == "DCL" then
956 world_doubleclick = true
959 if event.typ == "CHG" then
960 engine.setting_set("main_menu_singleplayer_world_idx",engine.get_textlist_index("sp_worlds"))
964 if fields["key_up"] then
965 local oldidx = engine.get_textlist_index("sp_worlds")
968 local newidx = oldidx -1
969 engine.setting_set("main_menu_singleplayer_world_idx",newidx)
973 if fields["key_down"] then
974 local oldidx = engine.get_textlist_index("sp_worlds")
976 if oldidx < #menu.filtered_game_list_raw() then
977 local newidx = oldidx + 1
978 engine.setting_set("main_menu_singleplayer_world_idx",newidx)
982 if fields["cb_creative_mode"] then
983 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
986 if fields["cb_enable_damage"] then
987 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
990 if fields["play"] ~= nil or
992 fields["key_enter"] then
993 local selected = engine.get_textlist_index("sp_worlds")
995 gamedata.selected_world = menu.filtered_index_to_plain(selected)
996 gamedata.singleplayer = true
998 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
999 engine.setting_set("main_menu_singleplayer_world_idx",selected)
1001 menu.update_last_game(gamedata.selected_world)
1007 if fields["world_create"] ~= nil then
1008 tabbuilder.current_tab = "dialog_create_world"
1009 tabbuilder.is_dialog = true
1010 tabbuilder.show_buttons = false
1013 if fields["world_delete"] ~= nil then
1014 local selected = engine.get_textlist_index("sp_worlds")
1015 if selected > 0 then
1016 menu.last_world = menu.filtered_index_to_plain(selected)
1017 if menu.lastworld() ~= nil and
1018 menu.lastworld().name ~= nil and
1019 menu.lastworld().name ~= "" then
1020 tabbuilder.current_tab = "dialog_delete_world"
1021 tabbuilder.is_dialog = true
1022 tabbuilder.show_buttons = false
1029 if fields["world_configure"] ~= nil then
1030 selected = engine.get_textlist_index("sp_worlds")
1031 if selected > 0 then
1032 modmgr.world_config_selected_world = menu.filtered_index_to_plain(selected)
1033 if modmgr.init_worldconfig() then
1034 tabbuilder.current_tab = "dialog_configure_world"
1035 tabbuilder.is_dialog = true
1036 tabbuilder.show_buttons = false
1042 --------------------------------------------------------------------------------
1043 function tabbuilder.tab_header()
1045 if tabbuilder.last_tab_index == nil then
1046 tabbuilder.last_tab_index = 1
1051 for i=1,#tabbuilder.current_buttons,1 do
1054 toadd = toadd .. ","
1057 toadd = toadd .. tabbuilder.current_buttons[i].caption
1059 return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
1062 --------------------------------------------------------------------------------
1063 function tabbuilder.handle_tab_buttons(fields)
1065 if fields["main_tab"] then
1066 local index = tonumber(fields["main_tab"])
1067 tabbuilder.last_tab_index = index
1068 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
1070 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1073 --handle tab changes
1074 if tabbuilder.current_tab ~= tabbuilder.old_tab then
1075 if tabbuilder.current_tab ~= "singleplayer" then
1076 menu.reset_gametype()
1080 if tabbuilder.current_tab == "singleplayer" then
1081 menu.update_gametype()
1084 tabbuilder.old_tab = tabbuilder.current_tab
1087 --------------------------------------------------------------------------------
1088 function tabbuilder.init()
1089 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1091 if tabbuilder.current_tab == nil or
1092 tabbuilder.current_tab == "" then
1093 tabbuilder.current_tab = "singleplayer"
1094 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
1098 --initialize tab buttons
1099 tabbuilder.last_tab = nil
1100 tabbuilder.show_buttons = true
1102 tabbuilder.current_buttons = {}
1103 table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
1104 table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
1105 table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
1106 table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
1108 if engine.setting_getbool("main_menu_game_mgr") then
1109 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
1112 if engine.setting_getbool("main_menu_mod_mgr") then
1113 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
1115 table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
1118 for i=1,#tabbuilder.current_buttons,1 do
1119 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
1120 tabbuilder.last_tab_index = i
1124 menu.update_gametype()
1127 --------------------------------------------------------------------------------
1128 function tabbuilder.tab_multiplayer()
1131 "vertlabel[0,-0.25;CLIENT]" ..
1132 "label[1,-0.25;Favorites:]"..
1133 "label[1,4.25;Address/Port]"..
1134 "label[9,0;Name/Password]" ..
1135 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
1136 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
1137 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]" ..
1138 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
1139 "field[9.25,1;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
1140 "pwdfield[9.25,1.75;2.5,0.5;te_pwd;]" ..
1141 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
1142 dump(engine.setting_getbool("public_serverlist")) .. "]" ..
1143 "textlist[1,0.35;7.5,3.35;favourites;"
1145 if #menu.favorites > 0 then
1146 retval = retval .. render_favourite(menu.favorites[1])
1148 for i=2,#menu.favorites,1 do
1149 retval = retval .. "," .. render_favourite(menu.favorites[i])
1153 print("cfav: " .. dump(menu.fav_selected))
1154 if menu.fav_selected ~= nil then
1155 retval = retval .. ";" .. menu.fav_selected .. "]"
1157 retval = retval .. ";0]"
1163 --------------------------------------------------------------------------------
1164 function tabbuilder.tab_server()
1165 local index = engine.setting_get("main_menu_last_world_idx")
1167 if index == nil then
1172 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1173 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1174 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1175 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
1176 "label[4,-0.25;Select World:]"..
1177 "vertlabel[0,-0.25;START SERVER]" ..
1178 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1179 dump(engine.setting_getbool("creative_mode")) .. "]"..
1180 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1181 dump(engine.setting_getbool("enable_damage")) .. "]"..
1182 "checkbox[0.5,1.15;cb_server_announce;Public;" ..
1183 dump(engine.setting_getbool("server_announce")) .. "]"..
1184 "field[0.8,3.2;3,0.5;te_playername;Name;" ..
1185 engine.setting_get("name") .. "]" ..
1186 "pwdfield[0.8,4.2;3,0.5;te_passwd;Password]" ..
1187 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
1188 "textlist[4,0.25;7.5,3.7;srv_worlds;"
1190 if #menu.worldlist > 0 then
1191 retval = retval .. menu.worldlist[1].name ..
1192 " \\[" .. menu.worldlist[1].gameid .. "\\]"
1194 for i=2,#menu.worldlist,1 do
1195 retval = retval .. "," .. menu.worldlist[i].name ..
1196 " \\[" .. menu.worldlist[i].gameid .. "\\]"
1200 retval = retval .. ";" .. index .. "]"
1205 --------------------------------------------------------------------------------
1206 function tabbuilder.tab_settings()
1207 return "vertlabel[0,0;SETTINGS]" ..
1208 "checkbox[1,0.75;cb_fancy_trees;Fancy trees;" .. dump(engine.setting_getbool("new_style_leaves")) .. "]"..
1209 "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
1210 "checkbox[1,1.75;cb_3d_clouds;3D Clouds;" .. dump(engine.setting_getbool("enable_3d_clouds")) .. "]"..
1211 "checkbox[1,2.25;cb_opaque_water;Opaque Water;" .. dump(engine.setting_getbool("opaque_water")) .. "]"..
1213 "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;" .. dump(engine.setting_getbool("mip_map")) .. "]"..
1214 "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter")) .. "]"..
1215 "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;" .. dump(engine.setting_getbool("bilinear_filter")) .. "]"..
1216 "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;" .. dump(engine.setting_getbool("trilinear_filter")) .. "]"..
1218 "checkbox[7.5,0.75;cb_shaders;Shaders;" .. dump(engine.setting_getbool("enable_shaders")) .. "]"..
1219 "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals")) .. "]"..
1220 "checkbox[7.5,1.75;cb_particles;Enable Particles;" .. dump(engine.setting_getbool("enable_particles")) .. "]"..
1221 "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;" .. dump(engine.setting_getbool("liquid_finite")) .. "]"..
1223 "button[1,3.75;2.25,0.5;btn_change_keys;Change keys]"
1226 --------------------------------------------------------------------------------
1227 function tabbuilder.tab_singleplayer()
1228 local index = engine.setting_get("main_menu_singleplayer_world_idx")
1230 if index == nil then
1234 return "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
1235 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
1236 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
1237 "button[8.5,4.95;3.25,0.5;play;Play]" ..
1238 "label[4,-0.25;Select World:]"..
1239 "vertlabel[0,-0.25;SINGLE PLAYER]" ..
1240 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
1241 dump(engine.setting_getbool("creative_mode")) .. "]"..
1242 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
1243 dump(engine.setting_getbool("enable_damage")) .. "]"..
1244 "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
1245 menu.filtered_game_list() ..
1246 ";" .. index .. "]" ..
1250 --------------------------------------------------------------------------------
1251 function tabbuilder.tab_credits()
1252 return "vertlabel[0,-0.5;CREDITS]" ..
1253 "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
1254 "label[0.5,3.3;http://minetest.net]" ..
1255 "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
1256 "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
1257 "#FFFF00Core Developers," ..
1258 "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
1259 "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
1260 "PilzAdam <pilzadam@minetest.net>," ..
1261 "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
1262 "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
1263 "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
1264 "proller <proler@gmail.com>,"..
1265 "sfan5 <sfan5@live.de>,"..
1266 "kahrl <kahrl@gmx.net>,"..
1268 "#FFFF00Active Contributors," ..
1270 "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
1271 "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
1272 "Jeija <jeija@mesecons.net>,"..
1273 "MirceaKitsune <mirceakitsune@gmail.com>,"..
1275 "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
1276 "0gb.us <0gb.us@0gb.us>,"..
1278 "#FFFF00Previous Contributors," ..
1279 "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
1280 "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
1281 "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
1282 "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
1283 "matttpt <matttpt@gmail.com>,"..
1284 "JacobF <queatz@gmail.com>,"..
1288 --------------------------------------------------------------------------------
1289 function tabbuilder.checkretval(retval)
1291 if retval ~= nil then
1292 if retval.current_tab ~= nil then
1293 tabbuilder.current_tab = retval.current_tab
1296 if retval.is_dialog ~= nil then
1297 tabbuilder.is_dialog = retval.is_dialog
1300 if retval.show_buttons ~= nil then
1301 tabbuilder.show_buttons = retval.show_buttons
1304 if retval.skipformupdate ~= nil then
1305 tabbuilder.skipformupdate = retval.skipformupdate
1310 --------------------------------------------------------------------------------
1311 --------------------------------------------------------------------------------
1312 -- initialize callbacks
1313 --------------------------------------------------------------------------------
1314 --------------------------------------------------------------------------------
1315 engine.button_handler = function(fields)
1316 --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1318 if fields["btn_error_confirm"] then
1319 gamedata.errormessage = nil
1322 local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1323 tabbuilder.checkretval(retval)
1325 retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1326 tabbuilder.checkretval(retval)
1328 retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1329 tabbuilder.checkretval(retval)
1331 if tabbuilder.current_tab == "dialog_create_world" then
1332 tabbuilder.handle_create_world_buttons(fields)
1335 if tabbuilder.current_tab == "dialog_delete_world" then
1336 tabbuilder.handle_delete_world_buttons(fields)
1339 if tabbuilder.current_tab == "singleplayer" then
1340 tabbuilder.handle_singleplayer_buttons(fields)
1343 if tabbuilder.current_tab == "multiplayer" then
1344 tabbuilder.handle_multiplayer_buttons(fields)
1347 if tabbuilder.current_tab == "settings" then
1348 tabbuilder.handle_settings_buttons(fields)
1351 if tabbuilder.current_tab == "server" then
1352 tabbuilder.handle_server_buttons(fields)
1356 tabbuilder.handle_tab_buttons(fields)
1359 menubar.handle_buttons(fields)
1361 if not tabbuilder.skipformupdate then
1365 tabbuilder.skipformupdate = false
1369 --------------------------------------------------------------------------------
1370 engine.event_handler = function(event)
1371 if event == "MenuQuit" then
1372 if tabbuilder.is_dialog then
1373 tabbuilder.is_dialog = false
1374 tabbuilder.show_buttons = true
1375 tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1383 --------------------------------------------------------------------------------
1384 --------------------------------------------------------------------------------
1386 --------------------------------------------------------------------------------
1387 --------------------------------------------------------------------------------