]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/mainmenu.lua
Show portnumber for ip adresses only
[dragonfireclient.git] / builtin / mainmenu.lua
1 os.setlocale("C", "numeric")
2
3 local scriptpath = engine.get_scriptdir()
4
5 mt_color_grey  = "#AAAAAA"
6 mt_color_blue  = "#0000DD"
7 mt_color_green = "#00DD00"
8 mt_color_dark_green = "#003300"
9
10 --for all other colors ask sfan5 to complete his worK!
11
12 dofile(scriptpath .. DIR_DELIM .. "filterlist.lua")
13 dofile(scriptpath .. DIR_DELIM .. "modmgr.lua")
14 dofile(scriptpath .. DIR_DELIM .. "modstore.lua")
15 dofile(scriptpath .. DIR_DELIM .. "gamemgr.lua")
16 dofile(scriptpath .. DIR_DELIM .. "mm_textures.lua")
17 dofile(scriptpath .. DIR_DELIM .. "mm_menubar.lua")
18
19 menu = {}
20 local tabbuilder = {}
21 local worldlist = nil
22
23 --------------------------------------------------------------------------------
24 function menu.render_favorite(spec,render_details)
25         local text = ""
26         
27         if spec.name ~= nil then
28                 text = text .. fs_escape_string(spec.name:trim())
29                 
30 --              if spec.description ~= nil and
31 --                      fs_escape_string(spec.description):trim() ~= "" then
32 --                      text = text .. " (" .. fs_escape_string(spec.description) .. ")"
33 --              end
34         else
35                 if spec.address ~= nil then
36                         text = text .. spec.address:trim()
37                         
38                         if spec.port ~= nil then
39                                 text = text .. ":" .. spec.port
40                         end
41                 end
42         end
43         
44         if not render_details then
45                 return text
46         end
47         
48         local details = ""
49         if spec.password == true then
50                 details = details .. "*"
51         else
52                 details = details .. "_"
53         end
54         
55         if spec.creative then
56                 details = details .. "C"
57         else
58                 details = details .. "_"
59         end
60         
61         if spec.damage then
62                 details = details .. "D"
63         else
64                 details = details .. "_"
65         end
66         
67         if spec.pvp then
68                 details = details .. "P"
69         else
70                 details = details .. "_"
71         end
72         details = details .. " "
73         
74         local playercount = ""
75         
76         if spec.clients ~= nil and
77                 spec.clients_max ~= nil then
78                 playercount = string.format("%03d",spec.clients) .. "/" ..
79                                                 string.format("%03d",spec.clients_max) .. " "
80         end
81         
82         return playercount .. fs_escape_string(details) ..  text
83 end
84
85 --------------------------------------------------------------------------------
86 os.tempfolder = function()
87         local filetocheck = os.tmpname()
88         os.remove(filetocheck)
89         
90         local randname = "MTTempModFolder_" .. math.random(0,10000)
91         if DIR_DELIM == "\\" then
92                 local tempfolder = os.getenv("TEMP")
93                 return tempfolder .. filetocheck
94         else
95                 local backstring = filetocheck:reverse()
96                 return filetocheck:sub(0,filetocheck:len()-backstring:find(DIR_DELIM)+1) ..randname
97         end
98
99 end
100
101 --------------------------------------------------------------------------------
102 function init_globals()
103         --init gamedata
104         gamedata.worldindex = 0
105         
106         worldlist = filterlist.create(
107                                         engine.get_worlds,
108                                         compare_worlds,
109                                         function(element,uid)
110                                                 if element.name == uid then
111                                                         return true
112                                                 end
113                                                 return false
114                                         end, --unique id compare fct
115                                         function(element,gameid)
116                                                 if element.gameid == gameid then
117                                                         return true
118                                                 end
119                                                 return false
120                                         end --filter fct
121                                         )
122                                         
123         filterlist.add_sort_mechanism(worldlist,"alphabetic",sort_worlds_alphabetic)
124         filterlist.set_sortmode(worldlist,"alphabetic")
125                                         
126 end
127
128 --------------------------------------------------------------------------------
129 function update_menu()
130
131         local formspec = "size[12,5.2]"
132         
133         -- handle errors
134         if gamedata.errormessage ~= nil then
135                 formspec = formspec ..
136                         "field[1,2;10,2;;ERROR: " ..
137                         gamedata.errormessage .. 
138                         ";]"..
139                         "button[4.5,4.2;3,0.5;btn_error_confirm;Ok]"
140         else
141                 formspec = formspec .. tabbuilder.gettab()
142         end
143
144         engine.update_formspec(formspec)
145 end
146
147 --------------------------------------------------------------------------------
148 function menu.render_world_list()
149         local retval = ""
150         
151         local current_worldlist = filterlist.get_list(worldlist)
152         
153         for i,v in ipairs(current_worldlist) do
154                 if retval ~= "" then
155                         retval = retval ..","
156                 end
157                 
158                 retval = retval .. v.name .. 
159                                         " \\[" .. v.gameid .. "\\]"
160         end
161
162         return retval
163 end
164
165 --------------------------------------------------------------------------------
166 function menu.init()
167         --init menu data
168         gamemgr.update_gamelist()
169         
170         menu.last_game  = tonumber(engine.setting_get("main_menu_last_game_idx"))
171         
172         if type(menu.last_game) ~= "number" then
173                 menu.last_game = 1
174         end
175
176         if engine.setting_getbool("public_serverlist") then
177                 menu.favorites = engine.get_favorites("online")
178         else
179                 menu.favorites = engine.get_favorites("local")
180         end
181         
182         menu.defaulttexturedir = engine.get_gamepath() .. DIR_DELIM .. ".." ..
183                                         DIR_DELIM .. "textures" .. DIR_DELIM .. "base" .. 
184                                         DIR_DELIM .. "pack" .. DIR_DELIM
185 end
186
187 --------------------------------------------------------------------------------
188 function menu.lastgame()
189         if menu.last_game > 0 and menu.last_game <= #gamemgr.games then
190                 return gamemgr.games[menu.last_game]
191         end
192         
193         if #gamemgr.games >= 1 then
194                 menu.last_game = 1
195                 return gamemgr.games[menu.last_game]
196         end
197         
198         --error case!!
199         return nil
200 end
201
202 --------------------------------------------------------------------------------
203 function menu.update_last_game()
204
205         local current_world = filterlist.get_raw_element(worldlist,
206                                                         engine.setting_get("mainmenu_last_selected_world")
207                                                         )
208                                                         
209         if current_world == nil then
210                 return
211         end
212                 
213         for i=1,#gamemgr.games,1 do             
214                 if gamemgr.games[i].id == current_world.gameid then
215                         menu.last_game = i
216                         engine.setting_set("main_menu_last_game_idx",menu.last_game)
217                         break
218                 end
219         end
220 end
221
222 --------------------------------------------------------------------------------
223 function menu.handle_key_up_down(fields,textlist,settingname)
224
225         if fields["key_up"] then
226                 local oldidx = engine.get_textlist_index(textlist)
227                 
228                 if oldidx > 1 then
229                         local newidx = oldidx -1
230                         engine.setting_set(settingname,
231                                 filterlist.get_raw_index(worldlist,newidx))
232                 end
233         end
234         
235         if fields["key_down"] then
236                 local oldidx = engine.get_textlist_index(textlist)
237                 
238                 if oldidx < filterlist.size(worldlist) then
239                         local newidx = oldidx + 1
240                         engine.setting_set(settingname,
241                                 filterlist.get_raw_index(worldlist,newidx))
242                 end
243         end
244 end
245
246 --------------------------------------------------------------------------------
247 function tabbuilder.dialog_create_world()
248         local mapgens = {"v6", "v7", "indev", "singlenode", "math"}
249
250         local current_mg = engine.setting_get("mg_name")
251
252         local mglist = ""
253         local selindex = 1
254         local i = 1
255         for k,v in pairs(mapgens) do
256                 if current_mg == v then
257                         selindex = i
258                 end
259                 i = i + 1
260                 mglist = mglist .. v .. ","
261         end
262         mglist = mglist:sub(1, -2)
263
264         local retval = 
265                 "label[2,0;World name]"..
266                 "label[2,1;Mapgen]"..
267                 "field[4.5,0.4;6,0.5;te_world_name;;]" ..
268                 "label[2,2;Game]"..
269                 "button[5,4.5;2.6,0.5;world_create_confirm;Create]" ..
270                 "button[7.5,4.5;2.8,0.5;world_create_cancel;Cancel]" ..
271                 "dropdown[4.2,1;6.3;dd_mapgen;" .. mglist .. ";" .. selindex .. "]" ..
272                 "textlist[4.2,1.9;5.8,2.3;games;" ..
273                 gamemgr.gamelist() ..
274                 ";" .. menu.last_game .. ";true]"
275
276         return retval
277 end
278
279 --------------------------------------------------------------------------------
280 function tabbuilder.dialog_delete_world()
281         return  "label[2,2;Delete World \"" .. filterlist.get_raw_list(worldlist)[menu.world_to_del].name .. "\"?]"..
282                         "button[3.5,4.2;2.6,0.5;world_delete_confirm;Yes]" ..
283                         "button[6,4.2;2.8,0.5;world_delete_cancel;No]"
284 end
285
286 --------------------------------------------------------------------------------
287 function tabbuilder.gettab()
288         local retval = ""
289         
290         if tabbuilder.show_buttons then
291                 retval = retval .. tabbuilder.tab_header()
292         end
293
294         if tabbuilder.current_tab == "singleplayer" then
295                 retval = retval .. tabbuilder.tab_singleplayer()
296         end
297         
298         if tabbuilder.current_tab == "multiplayer" then
299                 retval = retval .. tabbuilder.tab_multiplayer()
300         end
301
302         if tabbuilder.current_tab == "server" then
303                 retval = retval .. tabbuilder.tab_server()
304         end
305         
306         if tabbuilder.current_tab == "settings" then
307                 retval = retval .. tabbuilder.tab_settings()
308         end
309         
310         if tabbuilder.current_tab == "credits" then
311                 retval = retval .. tabbuilder.tab_credits()
312         end
313         
314         if tabbuilder.current_tab == "dialog_create_world" then
315                 retval = retval .. tabbuilder.dialog_create_world()
316         end
317         
318         if tabbuilder.current_tab == "dialog_delete_world" then
319                 retval = retval .. tabbuilder.dialog_delete_world()
320         end
321         
322         retval = retval .. modmgr.gettab(tabbuilder.current_tab)
323         retval = retval .. gamemgr.gettab(tabbuilder.current_tab)
324         retval = retval .. modstore.gettab(tabbuilder.current_tab)
325
326         return retval
327 end
328
329 --------------------------------------------------------------------------------
330 function tabbuilder.handle_create_world_buttons(fields)
331         
332         if fields["world_create_confirm"] or
333                 fields["key_enter"] then
334                 
335                 local worldname = fields["te_world_name"]
336                 local gameindex = engine.get_textlist_index("games")
337                 
338                 if gameindex > 0 and
339                         worldname ~= "" then
340                         
341                         local message = nil
342                         
343                         if not filterlist.uid_exists_raw(worldlist,worldname) then
344                                 engine.setting_set("mg_name",fields["dd_mapgen"])
345                                 message = engine.create_world(worldname,gameindex)
346                         else
347                                 message = "A world named \"" .. worldname .. "\" already exists"
348                         end
349                         
350                         if message ~= nil then
351                                 gamedata.errormessage = message
352                         else
353                                 menu.last_game = gameindex
354                                 engine.setting_set("main_menu_last_game_idx",gameindex)
355                                 
356                                 filterlist.refresh(worldlist)
357                                 engine.setting_set("mainmenu_last_selected_world",
358                                                                         filterlist.raw_index_by_uid(worldlist,worldname))
359                         end
360                 else
361                         gamedata.errormessage = "No worldname given or no game selected"
362                 end
363         end
364         
365         if fields["games"] then
366                 tabbuilder.skipformupdate = true
367                 return
368         end
369         
370         --close dialog
371         tabbuilder.is_dialog = false
372         tabbuilder.show_buttons = true
373         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
374 end
375
376 --------------------------------------------------------------------------------
377 function tabbuilder.handle_delete_world_buttons(fields)
378         
379         if fields["world_delete_confirm"] then
380                 if menu.world_to_del > 0 and 
381                         menu.world_to_del <= #filterlist.get_raw_list(worldlist) then
382                         engine.delete_world(menu.world_to_del)
383                         menu.world_to_del = 0
384                         filterlist.refresh(worldlist)
385                 end
386         end
387         
388         tabbuilder.is_dialog = false
389         tabbuilder.show_buttons = true
390         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
391 end
392
393 --------------------------------------------------------------------------------
394 function tabbuilder.handle_multiplayer_buttons(fields)
395         
396         if fields["te_name"] ~= nil then
397                 gamedata.playername = fields["te_name"]
398                 engine.setting_set("name", fields["te_name"])
399         end
400         
401         if fields["favourites"] ~= nil then
402                 local event = explode_textlist_event(fields["favourites"])
403                 if event.typ == "DCL" then
404                         gamedata.address = menu.favorites[event.index].address
405                         gamedata.port = menu.favorites[event.index].port
406                         gamedata.playername             = fields["te_name"]
407                         if fields["te_pwd"] ~= nil then
408                                 gamedata.password               = fields["te_pwd"]
409                         end
410                         gamedata.selected_world = 0
411                         
412                         if menu.favorites ~= nil then
413                                 gamedata.servername = menu.favorites[event.index].name
414                                 gamedata.serverdescription = menu.favorites[event.index].description
415                         end
416                         
417                         if gamedata.address ~= nil and
418                                 gamedata.port ~= nil then
419                                 
420                                 engine.start()
421                         end
422                 end
423                 
424                 if event.typ == "CHG" then
425                         local address = menu.favorites[event.index].address
426                         local port = menu.favorites[event.index].port
427                         
428                         if address ~= nil and
429                                 port ~= nil then
430                                 engine.setting_set("address",address)
431                                 engine.setting_set("port",port)
432                         end
433                         
434                         menu.fav_selected = event.index
435                 end
436                 return
437         end
438         
439         if fields["key_up"] ~= nil or
440                 fields["key_down"] ~= nil then
441                 
442                 local fav_idx = engine.get_textlist_index("favourites")
443                 
444                 if fields["key_up"] ~= nil and fav_idx > 1 then
445                         fav_idx = fav_idx -1
446                 else if fields["key_down"] and fav_idx < #menu.favorites then
447                         fav_idx = fav_idx +1
448                 end end
449                 
450                 local address = menu.favorites[fav_idx].address
451                 local port = menu.favorites[fav_idx].port
452                 
453                 if address ~= nil and
454                         port ~= nil then
455                         engine.setting_set("address",address)
456                         engine.setting_set("port",port)
457                 end
458                 
459                 menu.fav_selected = fav_idx
460                 return
461         end
462         
463         if fields["cb_public_serverlist"] ~= nil then
464                 engine.setting_setbool("public_serverlist",
465                         tabbuilder.tobool(fields["cb_public_serverlist"]))
466                         
467                 if engine.setting_getbool("public_serverlist") then
468                         menu.favorites = engine.get_favorites("online")
469                 else
470                         menu.favorites = engine.get_favorites("local")
471                 end
472                 menu.fav_selected = nil
473                 return
474         end
475
476         if fields["btn_delete_favorite"] ~= nil then
477                 local current_favourite = engine.get_textlist_index("favourites")
478                 engine.delete_favorite(current_favourite)
479                 menu.favorites = engine.get_favorites()
480                 menu.fav_selected = nil
481                 
482                 engine.setting_set("address","")
483                 engine.setting_get("port","")
484                 
485                 return
486         end
487
488         if fields["btn_mp_connect"] ~= nil or
489                 fields["key_enter"] then
490                 
491                 gamedata.playername             = fields["te_name"]
492                 gamedata.password               = fields["te_pwd"]
493                 gamedata.address                = fields["te_address"]
494                 gamedata.port                   = fields["te_port"]
495                 
496                 local fav_idx = engine.get_textlist_index("favourites")
497                 
498                 if fav_idx > 0 and fav_idx <= #menu.favorites and
499                         menu.favorites[fav_idx].address == fields["te_address"] and
500                         menu.favorites[fav_idx].port == fields["te_port"] then
501                         
502                         gamedata.servername                     = menu.favorites[fav_idx].name
503                         gamedata.serverdescription      = menu.favorites[fav_idx].description
504                 else
505                         gamedata.servername = ""
506                         gamedata.serverdescription = ""
507                 end
508
509                 gamedata.selected_world = 0
510                 
511                 engine.start()
512                 return
513         end
514 end
515
516 --------------------------------------------------------------------------------
517 function tabbuilder.handle_server_buttons(fields)
518
519         local world_doubleclick = false
520
521         if fields["srv_worlds"] ~= nil then
522                 local event = explode_textlist_event(fields["srv_worlds"])
523                 
524                 if event.typ == "DCL" then
525                         world_doubleclick = true
526                 end
527                 if event.typ == "CHG" then
528                         engine.setting_set("mainmenu_last_selected_world",
529                                 filterlist.get_raw_index(worldlist,engine.get_textlist_index("srv_worlds")))
530                 end
531         end
532         
533         menu.handle_key_up_down(fields,"srv_worlds","mainmenu_last_selected_world")
534         
535         if fields["cb_creative_mode"] then
536                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
537         end
538         
539         if fields["cb_enable_damage"] then
540                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
541         end
542
543         if fields["cb_server_announce"] then
544                 engine.setting_setbool("server_announce",tabbuilder.tobool(fields["cb_server_announce"]))
545         end
546         
547         if fields["start_server"] ~= nil or
548                 world_doubleclick or
549                 fields["key_enter"] then
550                 local selected = engine.get_textlist_index("srv_worlds")
551                 if selected > 0 then
552                         gamedata.playername             = fields["te_playername"]
553                         gamedata.password               = fields["te_passwd"]
554                         gamedata.port                   = fields["te_serverport"]
555                         gamedata.address                = ""
556                         gamedata.selected_world = filterlist.get_raw_index(worldlist,selected)
557                         
558                         menu.update_last_game(gamedata.selected_world)
559                         engine.start()
560                 end
561         end
562         
563         if fields["world_create"] ~= nil then
564                 tabbuilder.current_tab = "dialog_create_world"
565                 tabbuilder.is_dialog = true
566                 tabbuilder.show_buttons = false
567         end
568         
569         if fields["world_delete"] ~= nil then
570                 local selected = engine.get_textlist_index("srv_worlds")
571                 if selected > 0 and
572                         selected <= filterlist.size(worldlist) then
573                         local world = filterlist.get_list(worldlist)[selected]
574                         if world ~= nil and
575                                 world.name ~= nil and
576                                 world.name ~= "" then
577                                 menu.world_to_del = filterlist.get_raw_index(worldlist,selected)
578                                 tabbuilder.current_tab = "dialog_delete_world"
579                                 tabbuilder.is_dialog = true
580                                 tabbuilder.show_buttons = false
581                         else
582                                 menu.world_to_del = 0
583                         end
584                 end
585         end
586         
587         if fields["world_configure"] ~= nil then
588                 selected = engine.get_textlist_index("srv_worlds")
589                 if selected > 0 then
590                         modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected)
591                         if modmgr.init_worldconfig() then
592                                 tabbuilder.current_tab = "dialog_configure_world"
593                                 tabbuilder.is_dialog = true
594                                 tabbuilder.show_buttons = false
595                         end
596                 end
597         end
598 end
599
600 --------------------------------------------------------------------------------
601 function tabbuilder.tobool(text)
602         if text == "true" then
603                 return true
604         else
605                 return false
606         end
607 end
608
609 --------------------------------------------------------------------------------
610 function tabbuilder.handle_settings_buttons(fields)
611         if fields["cb_fancy_trees"] then
612                 engine.setting_setbool("new_style_leaves",tabbuilder.tobool(fields["cb_fancy_trees"]))
613         end
614         if fields["cb_smooth_lighting"] then
615                 engine.setting_setbool("smooth_lighting",tabbuilder.tobool(fields["cb_smooth_lighting"]))
616         end
617         if fields["cb_3d_clouds"] then
618                 engine.setting_setbool("enable_3d_clouds",tabbuilder.tobool(fields["cb_3d_clouds"]))
619         end
620         if fields["cb_opaque_water"] then
621                 engine.setting_setbool("opaque_water",tabbuilder.tobool(fields["cb_opaque_water"]))
622         end
623         if fields["old_style_modselection"] then
624                 engine.setting_setbool("old_style_mod_selection",tabbuilder.tobool(fields["old_style_modselection"]))
625         end
626         
627         if fields["cb_mipmapping"] then
628                 engine.setting_setbool("mip_map",tabbuilder.tobool(fields["cb_mipmapping"]))
629         end
630         if fields["cb_anisotrophic"] then
631                 engine.setting_setbool("anisotropic_filter",tabbuilder.tobool(fields["cb_anisotrophic"]))
632         end
633         if fields["cb_bilinear"] then
634                 engine.setting_setbool("bilinear_filter",tabbuilder.tobool(fields["cb_bilinear"]))
635         end
636         if fields["cb_trilinear"] then
637                 engine.setting_setbool("trilinear_filter",tabbuilder.tobool(fields["cb_trilinear"]))
638         end
639                         
640         if fields["cb_shaders"] then
641                 engine.setting_setbool("enable_shaders",tabbuilder.tobool(fields["cb_shaders"]))
642         end
643         if fields["cb_pre_ivis"] then
644                 engine.setting_setbool("preload_item_visuals",tabbuilder.tobool(fields["cb_pre_ivis"]))
645         end
646         if fields["cb_particles"] then
647                 engine.setting_setbool("enable_particles",tabbuilder.tobool(fields["cb_particles"]))
648         end
649         if fields["cb_finite_liquid"] then
650                 engine.setting_setbool("liquid_finite",tabbuilder.tobool(fields["cb_finite_liquid"]))
651         end
652
653         if fields["btn_change_keys"] ~= nil then
654                 engine.show_keys_menu()
655         end
656 end
657
658 --------------------------------------------------------------------------------
659 function tabbuilder.handle_singleplayer_buttons(fields)
660
661         local world_doubleclick = false
662
663         if fields["sp_worlds"] ~= nil then
664                 local event = explode_textlist_event(fields["sp_worlds"])
665                 
666                 if event.typ == "DCL" then
667                         world_doubleclick = true
668                 end
669                 
670                 if event.typ == "CHG" then
671                         engine.setting_set("mainmenu_last_selected_world",
672                                 filterlist.get_raw_index(worldlist,engine.get_textlist_index("sp_worlds")))
673                 end
674         end
675         
676         menu.handle_key_up_down(fields,"sp_worlds","mainmenu_last_selected_world")
677         
678         if fields["cb_creative_mode"] then
679                 engine.setting_setbool("creative_mode",tabbuilder.tobool(fields["cb_creative_mode"]))
680         end
681         
682         if fields["cb_enable_damage"] then
683                 engine.setting_setbool("enable_damage",tabbuilder.tobool(fields["cb_enable_damage"]))
684         end
685
686         if fields["play"] ~= nil or
687                 world_doubleclick or
688                 fields["key_enter"] then
689                 local selected = engine.get_textlist_index("sp_worlds")
690                 if selected > 0 then
691                         gamedata.selected_world = filterlist.get_raw_index(worldlist,selected)
692                         gamedata.singleplayer   = true
693                         
694                         menu.update_last_game(gamedata.selected_world)
695                         
696                         engine.start()
697                 end
698         end
699         
700         if fields["world_create"] ~= nil then
701                 tabbuilder.current_tab = "dialog_create_world"
702                 tabbuilder.is_dialog = true
703                 tabbuilder.show_buttons = false
704         end
705         
706         if fields["world_delete"] ~= nil then
707                 local selected = engine.get_textlist_index("sp_worlds")
708                 if selected > 0 and
709                         selected <= filterlist.size(worldlist) then
710                         local world = filterlist.get_list(worldlist)[selected]
711                         if world ~= nil and
712                                 world.name ~= nil and
713                                 world.name ~= "" then
714                                 menu.world_to_del = filterlist.get_raw_index(worldlist,selected)
715                                 tabbuilder.current_tab = "dialog_delete_world"
716                                 tabbuilder.is_dialog = true
717                                 tabbuilder.show_buttons = false
718                         else
719                                 menu.world_to_del = 0
720                         end
721                 end
722         end
723         
724         if fields["world_configure"] ~= nil then
725                 selected = engine.get_textlist_index("sp_worlds")
726                 if selected > 0 then
727                         modmgr.world_config_selected_world = filterlist.get_raw_index(worldlist,selected)
728                         if modmgr.init_worldconfig() then
729                                 tabbuilder.current_tab = "dialog_configure_world"
730                                 tabbuilder.is_dialog = true
731                                 tabbuilder.show_buttons = false
732                         end
733                 end
734         end
735 end
736
737 --------------------------------------------------------------------------------
738 function tabbuilder.tab_header()
739
740         if tabbuilder.last_tab_index == nil then
741                 tabbuilder.last_tab_index = 1
742         end
743         
744         local toadd = ""
745         
746         for i=1,#tabbuilder.current_buttons,1 do
747                 
748                 if toadd ~= "" then
749                         toadd = toadd .. ","
750                 end
751                 
752                 toadd = toadd .. tabbuilder.current_buttons[i].caption
753         end
754         return "tabheader[-0.3,-0.99;main_tab;" .. toadd ..";" .. tabbuilder.last_tab_index .. ";true;false]"
755 end
756
757 --------------------------------------------------------------------------------
758 function tabbuilder.handle_tab_buttons(fields)
759
760         if fields["main_tab"] then
761                 local index = tonumber(fields["main_tab"])
762                 tabbuilder.last_tab_index = index
763                 tabbuilder.current_tab = tabbuilder.current_buttons[index].name
764                 
765                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
766         end
767         
768         --handle tab changes
769         if tabbuilder.current_tab ~= tabbuilder.old_tab then
770                 if tabbuilder.current_tab ~= "singleplayer" then
771                         menu.update_gametype(true)
772                 end
773         end
774         
775         if tabbuilder.current_tab == "singleplayer" then
776                 menu.update_gametype()
777         end
778         
779         tabbuilder.old_tab = tabbuilder.current_tab
780 end
781
782 --------------------------------------------------------------------------------
783 function tabbuilder.init()
784         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
785         
786         if tabbuilder.current_tab == nil or
787                 tabbuilder.current_tab == "" then
788                 tabbuilder.current_tab = "singleplayer"
789                 engine.setting_set("main_menu_tab",tabbuilder.current_tab)
790         end
791         
792         --initialize tab buttons
793         tabbuilder.last_tab = nil
794         tabbuilder.show_buttons = true
795         
796         tabbuilder.current_buttons = {}
797         table.insert(tabbuilder.current_buttons,{name="singleplayer", caption="Singleplayer"})
798         table.insert(tabbuilder.current_buttons,{name="multiplayer", caption="Client"})
799         table.insert(tabbuilder.current_buttons,{name="server", caption="Server"})
800         table.insert(tabbuilder.current_buttons,{name="settings", caption="Settings"})
801         
802         if engine.setting_getbool("main_menu_game_mgr") then
803                 table.insert(tabbuilder.current_buttons,{name="game_mgr", caption="Games"})
804         end
805         
806         if engine.setting_getbool("main_menu_mod_mgr") then
807                 table.insert(tabbuilder.current_buttons,{name="mod_mgr", caption="Mods"})
808         end
809         table.insert(tabbuilder.current_buttons,{name="credits", caption="Credits"})
810         
811         
812         for i=1,#tabbuilder.current_buttons,1 do
813                 if tabbuilder.current_buttons[i].name == tabbuilder.current_tab then
814                         tabbuilder.last_tab_index = i
815                 end
816         end
817         
818         menu.update_gametype()
819 end
820
821 --------------------------------------------------------------------------------
822 function tabbuilder.tab_multiplayer()
823
824         local retval =
825                 "vertlabel[0,-0.25;CLIENT]" ..
826                 "label[1,-0.25;Favorites:]"..
827                 "label[1,4.25;Address/Port]"..
828                 "label[9,2.75;Name/Password]" ..
829                 "field[1.25,5.25;5.5,0.5;te_address;;" ..engine.setting_get("address") .."]" ..
830                 "field[6.75,5.25;2.25,0.5;te_port;;" ..engine.setting_get("port") .."]" ..
831                 "checkbox[1,3.6;cb_public_serverlist;Public Serverlist;" ..
832                 dump(engine.setting_getbool("public_serverlist")) .. "]"
833                 
834         if not engine.setting_getbool("public_serverlist") then
835                 retval = retval .. 
836                 "button[6.45,3.95;2.25,0.5;btn_delete_favorite;Delete]"
837         end
838         
839         retval = retval ..
840                 "button[9,4.95;2.5,0.5;btn_mp_connect;Connect]" ..
841                 "field[9.3,3.75;2.5,0.5;te_name;;" ..engine.setting_get("name") .."]" ..
842                 "pwdfield[9.3,4.5;2.5,0.5;te_pwd;]" ..
843                 "textarea[9.3,0.25;2.5,2.75;;"
844         if menu.fav_selected ~= nil and 
845                 menu.favorites[menu.fav_selected].description ~= nil then
846                 retval = retval .. 
847                         fs_escape_string(menu.favorites[menu.fav_selected].description,true)
848         end
849         
850         retval = retval .. 
851                 ";]" ..
852                 "textlist[1,0.35;7.5,3.35;favourites;"
853
854         local render_details = engine.setting_getbool("public_serverlist")
855
856         if #menu.favorites > 0 then
857                 retval = retval .. menu.render_favorite(menu.favorites[1],render_details)
858                 
859                 for i=2,#menu.favorites,1 do
860                         retval = retval .. "," .. menu.render_favorite(menu.favorites[i],render_details)
861                 end
862         end
863
864         if menu.fav_selected ~= nil then
865                 retval = retval .. ";" .. menu.fav_selected .. "]"
866         else
867                 retval = retval .. ";0]"
868         end
869
870         return retval
871 end
872
873 --------------------------------------------------------------------------------
874 function tabbuilder.tab_server()
875
876         local index = filterlist.get_current_index(worldlist,
877                                 tonumber(engine.setting_get("mainmenu_last_selected_world"))
878                                 )
879         
880         local retval = 
881                 "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
882                 "button[6.5,4.15;2.8,0.5;world_create;New]" ..
883                 "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
884                 "button[8.5,4.9;3.25,0.5;start_server;Start Game]" ..
885                 "label[4,-0.25;Select World:]"..
886                 "vertlabel[0,-0.25;START SERVER]" ..
887                 "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
888                 dump(engine.setting_getbool("creative_mode")) .. "]"..
889                 "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
890                 dump(engine.setting_getbool("enable_damage")) .. "]"..
891                 "checkbox[0.5,1.15;cb_server_announce;Public;" ..
892                 dump(engine.setting_getbool("server_announce")) .. "]"..
893                 "field[0.8,3.2;3,0.5;te_playername;Name;" ..
894                 engine.setting_get("name") .. "]" ..
895                 "pwdfield[0.8,4.2;3,0.5;te_passwd;Password]" ..
896                 "field[0.8,5.2;3,0.5;te_serverport;Server Port;30000]" ..
897                 "textlist[4,0.25;7.5,3.7;srv_worlds;" ..
898                 menu.render_world_list() ..
899                 ";" .. index .. "]"
900                 
901         return retval
902 end
903
904 --------------------------------------------------------------------------------
905 function tabbuilder.tab_settings()
906         return  "vertlabel[0,0;SETTINGS]" ..
907                         "checkbox[1,0.75;cb_fancy_trees;Fancy trees;"           .. dump(engine.setting_getbool("new_style_leaves"))     .. "]"..
908                         "checkbox[1,1.25;cb_smooth_lighting;Smooth Lighting;".. dump(engine.setting_getbool("smooth_lighting")) .. "]"..
909                         "checkbox[1,1.75;cb_3d_clouds;3D Clouds;"                       .. dump(engine.setting_getbool("enable_3d_clouds"))     .. "]"..
910                         "checkbox[1,2.25;cb_opaque_water;Opaque Water;"                 .. dump(engine.setting_getbool("opaque_water"))         .. "]"..
911                         "checkbox[1,2.75;old_style_modselection;Old style modmgr;" .. dump(engine.setting_getbool("old_style_mod_selection"))           .. "]"..
912                         
913                         "checkbox[4,0.75;cb_mipmapping;Mip-Mapping;"            .. dump(engine.setting_getbool("mip_map"))                      .. "]"..
914                         "checkbox[4,1.25;cb_anisotrophic;Anisotropic Filtering;".. dump(engine.setting_getbool("anisotropic_filter"))   .. "]"..
915                         "checkbox[4,1.75;cb_bilinear;Bi-Linear Filtering;"      .. dump(engine.setting_getbool("bilinear_filter"))      .. "]"..
916                         "checkbox[4,2.25;cb_trilinear;Tri-Linear Filtering;"    .. dump(engine.setting_getbool("trilinear_filter"))     .. "]"..
917                         
918                         "checkbox[7.5,0.75;cb_shaders;Shaders;"                         .. dump(engine.setting_getbool("enable_shaders"))               .. "]"..
919                         "checkbox[7.5,1.25;cb_pre_ivis;Preload item visuals;".. dump(engine.setting_getbool("preload_item_visuals"))    .. "]"..
920                         "checkbox[7.5,1.75;cb_particles;Enable Particles;"      .. dump(engine.setting_getbool("enable_particles"))     .. "]"..
921                         "checkbox[7.5,2.25;cb_finite_liquid;Finite Liquid;"     .. dump(engine.setting_getbool("liquid_finite"))                .. "]"..
922                         
923                         "button[1,4.25;2.25,0.5;btn_change_keys;Change keys]"
924 end
925
926 --------------------------------------------------------------------------------
927 function tabbuilder.tab_singleplayer()
928         
929         local index = filterlist.get_current_index(worldlist,
930                                 tonumber(engine.setting_get("mainmenu_last_selected_world"))
931                                 )
932
933         return  "button[4,4.15;2.6,0.5;world_delete;Delete]" ..
934                         "button[6.5,4.15;2.8,0.5;world_create;New]" ..
935                         "button[9.2,4.15;2.55,0.5;world_configure;Configure]" ..
936                         "button[8.5,4.95;3.25,0.5;play;Play]" ..
937                         "label[4,-0.25;Select World:]"..
938                         "vertlabel[0,-0.25;SINGLE PLAYER]" ..
939                         "checkbox[0.5,0.25;cb_creative_mode;Creative Mode;" ..
940                         dump(engine.setting_getbool("creative_mode")) .. "]"..
941                         "checkbox[0.5,0.7;cb_enable_damage;Enable Damage;" ..
942                         dump(engine.setting_getbool("enable_damage")) .. "]"..
943                         "textlist[4,0.25;7.5,3.7;sp_worlds;" ..
944                         menu.render_world_list() ..
945                         ";" .. index .. "]" ..
946                         menubar.formspec
947 end
948
949 --------------------------------------------------------------------------------
950 function tabbuilder.tab_credits()
951         return  "vertlabel[0,-0.5;CREDITS]" ..
952                         "label[0.5,3;Minetest " .. engine.get_version() .. "]" ..
953                         "label[0.5,3.3;http://minetest.net]" .. 
954                         "image[0.5,1;" .. menu.defaulttexturedir .. "logo.png]" ..
955                         "textlist[3.5,-0.25;8.5,5.8;list_credits;" ..
956                         "#FFFF00Core Developers," ..
957                         "Perttu Ahola (celeron55) <celeron55@gmail.com>,"..
958                         "Ryan Kwolek (kwolekr) <kwolekr@minetest.net>,"..
959                         "PilzAdam <pilzadam@minetest.net>," ..
960                         "IIya Zhuravlev (thexyz) <xyz@minetest.net>,"..
961                         "Lisa Milne (darkrose) <lisa@ltmnet.com>,"..
962                         "Maciej Kasatkin (RealBadAngel) <mk@realbadangel.pl>,"..
963                         "proller <proler@gmail.com>,"..
964                         "sfan5 <sfan5@live.de>,"..
965                         "kahrl <kahrl@gmx.net>,"..
966                         ","..
967                         "#FFFF00Active Contributors," ..
968                         "sapier,"..
969                         "Vanessa Ezekowitz (VanessaE) <vanessaezekowitz@gmail.com>,"..
970                         "Jurgen Doser (doserj) <jurgen.doser@gmail.com>,"..
971                         "Jeija <jeija@mesecons.net>,"..
972                         "MirceaKitsune <mirceakitsune@gmail.com>,"..
973                         "ShadowNinja,"..
974                         "dannydark <the_skeleton_of_a_child@yahoo.co.uk>,"..
975                         "0gb.us <0gb.us@0gb.us>,"..
976                         "," ..
977                         "#FFFF00Previous Contributors," ..
978                         "Guiseppe Bilotta (Oblomov) <guiseppe.bilotta@gmail.com>,"..
979                         "Jonathan Neuschafer <j.neuschaefer@gmx.net>,"..
980                         "Nils Dagsson Moskopp (erlehmann) <nils@dieweltistgarnichtso.net>,"..
981                         "Constantin Wenger (SpeedProg) <constantin.wenger@googlemail.com>,"..
982                         "matttpt <matttpt@gmail.com>,"..
983                         "JacobF <queatz@gmail.com>,"..
984                         ";0;true]"
985 end
986
987 --------------------------------------------------------------------------------
988 function tabbuilder.checkretval(retval)
989
990         if retval ~= nil then
991                 if retval.current_tab ~= nil then
992                         tabbuilder.current_tab = retval.current_tab
993                 end
994                 
995                 if retval.is_dialog ~= nil then
996                         tabbuilder.is_dialog = retval.is_dialog
997                 end
998                 
999                 if retval.show_buttons ~= nil then
1000                         tabbuilder.show_buttons = retval.show_buttons
1001                 end
1002                 
1003                 if retval.skipformupdate ~= nil then
1004                         tabbuilder.skipformupdate = retval.skipformupdate
1005                 end
1006         end
1007 end
1008
1009 --------------------------------------------------------------------------------
1010 --------------------------------------------------------------------------------
1011 -- initialize callbacks
1012 --------------------------------------------------------------------------------
1013 --------------------------------------------------------------------------------
1014 engine.button_handler = function(fields)
1015         --print("Buttonhandler: tab: " .. tabbuilder.current_tab .. " fields: " .. dump(fields))
1016         
1017         if fields["btn_error_confirm"] then
1018                 gamedata.errormessage = nil
1019         end
1020         
1021         local retval = modmgr.handle_buttons(tabbuilder.current_tab,fields)
1022         tabbuilder.checkretval(retval)
1023         
1024         retval = gamemgr.handle_buttons(tabbuilder.current_tab,fields)
1025         tabbuilder.checkretval(retval)
1026         
1027         retval = modstore.handle_buttons(tabbuilder.current_tab,fields)
1028         tabbuilder.checkretval(retval)
1029         
1030         if tabbuilder.current_tab == "dialog_create_world" then
1031                 tabbuilder.handle_create_world_buttons(fields)
1032         end
1033         
1034         if tabbuilder.current_tab == "dialog_delete_world" then
1035                 tabbuilder.handle_delete_world_buttons(fields)
1036         end
1037         
1038         if tabbuilder.current_tab == "singleplayer" then
1039                 tabbuilder.handle_singleplayer_buttons(fields)
1040         end
1041         
1042         if tabbuilder.current_tab == "multiplayer" then
1043                 tabbuilder.handle_multiplayer_buttons(fields)
1044         end
1045         
1046         if tabbuilder.current_tab == "settings" then
1047                 tabbuilder.handle_settings_buttons(fields)
1048         end
1049         
1050         if tabbuilder.current_tab == "server" then
1051                 tabbuilder.handle_server_buttons(fields)
1052         end
1053         
1054         --tab buttons
1055         tabbuilder.handle_tab_buttons(fields)
1056         
1057         --menubar buttons
1058         menubar.handle_buttons(fields)
1059         
1060         if not tabbuilder.skipformupdate then
1061                 --update menu
1062                 update_menu()
1063         else
1064                 tabbuilder.skipformupdate = false
1065         end
1066 end
1067
1068 --------------------------------------------------------------------------------
1069 engine.event_handler = function(event)
1070         if event == "MenuQuit" then
1071                 if tabbuilder.is_dialog then
1072                         tabbuilder.is_dialog = false
1073                         tabbuilder.show_buttons = true
1074                         tabbuilder.current_tab = engine.setting_get("main_menu_tab")
1075                         menu.update_gametype()
1076                         update_menu()
1077                 else
1078                         engine.close()
1079                 end
1080         end
1081 end
1082
1083 --------------------------------------------------------------------------------
1084 function menu.update_gametype(reset)
1085         if reset then
1086                 mm_texture.reset()
1087                 engine.set_topleft_text("")
1088                 filterlist.set_filtercriteria(worldlist,nil)
1089         else
1090                 local game = menu.lastgame()
1091                 mm_texture.update(tabbuilder.current_tab,game)
1092                 engine.set_topleft_text(game.name)
1093                 filterlist.set_filtercriteria(worldlist,game.id)
1094         end
1095 end
1096
1097 --------------------------------------------------------------------------------
1098 --------------------------------------------------------------------------------
1099 -- menu startup
1100 --------------------------------------------------------------------------------
1101 --------------------------------------------------------------------------------
1102 init_globals()
1103 mm_texture.init()
1104 menu.init()
1105 tabbuilder.init()
1106 menubar.refresh()
1107 modstore.init()
1108
1109
1110 update_menu()