]> git.lizzy.rs Git - dragonfireclient.git/blob - builtin/mainmenu/tab_local.lua
Deprecate game.conf name, use title instead (#12030)
[dragonfireclient.git] / builtin / mainmenu / tab_local.lua
1 --Minetest
2 --Copyright (C) 2014 sapier
3 --
4 --This program is free software; you can redistribute it and/or modify
5 --it under the terms of the GNU Lesser General Public License as published by
6 --the Free Software Foundation; either version 2.1 of the License, or
7 --(at your option) any later version.
8 --
9 --This program is distributed in the hope that it will be useful,
10 --but WITHOUT ANY WARRANTY; without even the implied warranty of
11 --MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 --GNU Lesser General Public License for more details.
13 --
14 --You should have received a copy of the GNU Lesser General Public License along
15 --with this program; if not, write to the Free Software Foundation, Inc.,
16 --51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18
19 local enable_gamebar = PLATFORM ~= "Android"
20 local current_game, singleplayer_refresh_gamebar
21 local valid_disabled_settings = {
22         ["enable_damage"]=true,
23         ["creative_mode"]=true,
24         ["enable_server"]=true,
25 }
26
27 if enable_gamebar then
28         -- Currently chosen game in gamebar for theming and filtering
29         function current_game()
30                 local last_game_id = core.settings:get("menu_last_game")
31                 local game = pkgmgr.find_by_gameid(last_game_id)
32
33                 return game
34         end
35
36         -- Apply menu changes from given game
37         function apply_game(game)
38                 core.set_topleft_text(game.name)
39                 core.settings:set("menu_last_game", game.id)
40                 menudata.worldlist:set_filtercriteria(game.id)
41
42                 mm_game_theme.update("singleplayer", game) -- this refreshes the formspec
43
44                 local index = filterlist.get_current_index(menudata.worldlist,
45                         tonumber(core.settings:get("mainmenu_last_selected_world")))
46                 if not index or index < 1 then
47                         local selected = core.get_textlist_index("sp_worlds")
48                         if selected ~= nil and selected < #menudata.worldlist:get_list() then
49                                 index = selected
50                         else
51                                 index = #menudata.worldlist:get_list()
52                         end
53                 end
54                 menu_worldmt_legacy(index)
55         end
56
57         function singleplayer_refresh_gamebar()
58
59                 local old_bar = ui.find_by_name("game_button_bar")
60                 if old_bar ~= nil then
61                         old_bar:delete()
62                 end
63
64                 local function game_buttonbar_button_handler(fields)
65                         if fields.game_open_cdb then
66                                 local maintab = ui.find_by_name("maintab")
67                                 local dlg = create_store_dlg("game")
68                                 dlg:set_parent(maintab)
69                                 maintab:hide()
70                                 dlg:show()
71                                 return true
72                         end
73
74                         for _, game in ipairs(pkgmgr.games) do
75                                 if fields["game_btnbar_" .. game.id] then
76                                         apply_game(game)
77                                         return true
78                                 end
79                         end
80                 end
81
82                 local btnbar = buttonbar_create("game_button_bar",
83                         game_buttonbar_button_handler,
84                         {x=-0.3,y=5.9}, "horizontal", {x=12.4,y=1.15})
85
86                 for _, game in ipairs(pkgmgr.games) do
87                         local btn_name = "game_btnbar_" .. game.id
88
89                         local image = nil
90                         local text = nil
91                         local tooltip = core.formspec_escape(game.title)
92
93                         if (game.menuicon_path or "") ~= "" then
94                                 image = core.formspec_escape(game.menuicon_path)
95                         else
96                                 local part1 = game.id:sub(1,5)
97                                 local part2 = game.id:sub(6,10)
98                                 local part3 = game.id:sub(11)
99
100                                 text = part1 .. "\n" .. part2
101                                 if part3 ~= "" then
102                                         text = text .. "\n" .. part3
103                                 end
104                         end
105                         btnbar:add_button(btn_name, text, image, tooltip)
106                 end
107
108                 local plus_image = core.formspec_escape(defaulttexturedir .. "plus.png")
109                 btnbar:add_button("game_open_cdb", "", plus_image, fgettext("Install games from ContentDB"))
110         end
111 else
112         -- Currently chosen game in gamebar: no gamebar -> no "current" game
113         function current_game()
114                 return nil
115         end
116 end
117
118 local function get_disabled_settings(game)
119         if not game then
120                 return {}
121         end
122
123         local gameconfig = Settings(game.path .. "/game.conf")
124         local disabled_settings = {}
125         if gameconfig then
126                 local disabled_settings_str = (gameconfig:get("disabled_settings") or ""):split()
127                 for _, value in pairs(disabled_settings_str) do
128                         local state = false
129                         value = value:trim()
130                         if string.sub(value, 1, 1) == "!" then
131                                 state = true
132                                 value = string.sub(value, 2)
133                         end
134                         if valid_disabled_settings[value] then
135                                 disabled_settings[value] = state
136                         else
137                                 core.log("error", "Invalid disabled setting in game.conf: "..tostring(value))
138                         end
139                 end
140         end
141         return disabled_settings
142 end
143
144 local function get_formspec(tabview, name, tabdata)
145         local retval = ""
146
147         local index = filterlist.get_current_index(menudata.worldlist,
148                                 tonumber(core.settings:get("mainmenu_last_selected_world")))
149         local list = menudata.worldlist:get_list()
150         local world = list and index and list[index]
151         local game
152         if world then
153                 game = pkgmgr.find_by_gameid(world.gameid)
154         else
155                 game = current_game()
156         end
157         local disabled_settings = get_disabled_settings(game)
158
159         local creative, damage, host = "", "", ""
160
161         -- Y offsets for game settings checkboxes
162         local y = -0.2
163         local yo = 0.45
164
165         if disabled_settings["creative_mode"] == nil then
166                 creative = "checkbox[0,"..y..";cb_creative_mode;".. fgettext("Creative Mode") .. ";" ..
167                         dump(core.settings:get_bool("creative_mode")) .. "]"
168                 y = y + yo
169         end
170         if disabled_settings["enable_damage"] == nil then
171                 damage = "checkbox[0,"..y..";cb_enable_damage;".. fgettext("Enable Damage") .. ";" ..
172                         dump(core.settings:get_bool("enable_damage")) .. "]"
173                 y = y + yo
174         end
175         if disabled_settings["enable_server"] == nil then
176                 host = "checkbox[0,"..y..";cb_server;".. fgettext("Host Server") ..";" ..
177                         dump(core.settings:get_bool("enable_server")) .. "]"
178                 y = y + yo
179         end
180
181         retval = retval ..
182                         "button[3.9,3.8;2.8,1;world_delete;".. fgettext("Delete") .. "]" ..
183                         "button[6.55,3.8;2.8,1;world_configure;".. fgettext("Select Mods") .. "]" ..
184                         "button[9.2,3.8;2.8,1;world_create;".. fgettext("New") .. "]" ..
185                         "label[3.9,-0.05;".. fgettext("Select World:") .. "]"..
186                         creative ..
187                         damage ..
188                         host ..
189                         "textlist[3.9,0.4;7.9,3.45;sp_worlds;" ..
190                         menu_render_worldlist(not enable_gamebar) ..
191                         ";" .. index .. "]"
192
193         if core.settings:get_bool("enable_server") and disabled_settings["enable_server"] == nil then
194                 retval = retval ..
195                                 "button[7.9,4.75;4.1,1;play;".. fgettext("Host Game") .. "]" ..
196                                 "checkbox[0,"..y..";cb_server_announce;" .. fgettext("Announce Server") .. ";" ..
197                                 dump(core.settings:get_bool("server_announce")) .. "]" ..
198                                 "field[0.3,2.85;3.8,0.5;te_playername;" .. fgettext("Name") .. ";" ..
199                                 core.formspec_escape(core.settings:get("name")) .. "]" ..
200                                 "pwdfield[0.3,4.05;3.8,0.5;te_passwd;" .. fgettext("Password") .. "]"
201
202                 local bind_addr = core.settings:get("bind_address")
203                 if bind_addr ~= nil and bind_addr ~= "" then
204                         retval = retval ..
205                                 "field[0.3,5.25;2.5,0.5;te_serveraddr;" .. fgettext("Bind Address") .. ";" ..
206                                 core.formspec_escape(core.settings:get("bind_address")) .. "]" ..
207                                 "field[2.85,5.25;1.25,0.5;te_serverport;" .. fgettext("Port") .. ";" ..
208                                 core.formspec_escape(core.settings:get("port")) .. "]"
209                 else
210                         retval = retval ..
211                                 "field[0.3,5.25;3.8,0.5;te_serverport;" .. fgettext("Server Port") .. ";" ..
212                                 core.formspec_escape(core.settings:get("port")) .. "]"
213                 end
214         else
215                 retval = retval ..
216                                 "button[7.9,4.75;4.1,1;play;" .. fgettext("Play Game") .. "]"
217         end
218
219         return retval
220 end
221
222 local function main_button_handler(this, fields, name, tabdata)
223
224         assert(name == "local")
225
226         local world_doubleclick = false
227
228         if fields["sp_worlds"] ~= nil then
229                 local event = core.explode_textlist_event(fields["sp_worlds"])
230                 local selected = core.get_textlist_index("sp_worlds")
231
232                 menu_worldmt_legacy(selected)
233
234                 if event.type == "DCL" then
235                         world_doubleclick = true
236                 end
237
238                 if event.type == "CHG" and selected ~= nil then
239                         core.settings:set("mainmenu_last_selected_world",
240                                 menudata.worldlist:get_raw_index(selected))
241                         return true
242                 end
243         end
244
245         if menu_handle_key_up_down(fields,"sp_worlds","mainmenu_last_selected_world") then
246                 return true
247         end
248
249         if fields["cb_creative_mode"] then
250                 core.settings:set("creative_mode", fields["cb_creative_mode"])
251                 local selected = core.get_textlist_index("sp_worlds")
252                 menu_worldmt(selected, "creative_mode", fields["cb_creative_mode"])
253
254                 return true
255         end
256
257         if fields["cb_enable_damage"] then
258                 core.settings:set("enable_damage", fields["cb_enable_damage"])
259                 local selected = core.get_textlist_index("sp_worlds")
260                 menu_worldmt(selected, "enable_damage", fields["cb_enable_damage"])
261
262                 return true
263         end
264
265         if fields["cb_server"] then
266                 core.settings:set("enable_server", fields["cb_server"])
267
268                 return true
269         end
270
271         if fields["cb_server_announce"] then
272                 core.settings:set("server_announce", fields["cb_server_announce"])
273                 local selected = core.get_textlist_index("srv_worlds")
274                 menu_worldmt(selected, "server_announce", fields["cb_server_announce"])
275
276                 return true
277         end
278
279         if fields["play"] ~= nil or world_doubleclick or fields["key_enter"] then
280                 local selected = core.get_textlist_index("sp_worlds")
281                 gamedata.selected_world = menudata.worldlist:get_raw_index(selected)
282
283                 if selected == nil or gamedata.selected_world == 0 then
284                         gamedata.errormessage =
285                                         fgettext("No world created or selected!")
286                         return true
287                 end
288
289                 -- Update last game
290                 local world = menudata.worldlist:get_raw_element(gamedata.selected_world)
291                 local game_obj
292                 if world then
293                         game_obj = pkgmgr.find_by_gameid(world.gameid)
294                         core.settings:set("menu_last_game", game_obj.id)
295                 end
296
297                 local disabled_settings = get_disabled_settings(game_obj)
298                 for k, _ in pairs(valid_disabled_settings) do
299                         local v = disabled_settings[k]
300                         if v ~= nil then
301                                 if k == "enable_server" and v == true then
302                                         error("Setting 'enable_server' cannot be force-enabled! The game.conf needs to be fixed.")
303                                 end
304                                 core.settings:set_bool(k, disabled_settings[k])
305                         end
306                 end
307
308                 if core.settings:get_bool("enable_server") then
309                         gamedata.playername = fields["te_playername"]
310                         gamedata.password   = fields["te_passwd"]
311                         gamedata.port       = fields["te_serverport"]
312                         gamedata.address    = ""
313
314                         core.settings:set("port",gamedata.port)
315                         if fields["te_serveraddr"] ~= nil then
316                                 core.settings:set("bind_address",fields["te_serveraddr"])
317                         end
318                 else
319                         gamedata.singleplayer = true
320                 end
321
322                 core.start()
323                 return true
324         end
325
326         if fields["world_create"] ~= nil then
327                 local create_world_dlg = create_create_world_dlg(enable_gamebar)
328                 create_world_dlg:set_parent(this)
329                 this:hide()
330                 create_world_dlg:show()
331                 mm_game_theme.update("singleplayer", current_game())
332                 return true
333         end
334
335         if fields["world_delete"] ~= nil then
336                 local selected = core.get_textlist_index("sp_worlds")
337                 if selected ~= nil and
338                         selected <= menudata.worldlist:size() then
339                         local world = menudata.worldlist:get_list()[selected]
340                         if world ~= nil and
341                                 world.name ~= nil and
342                                 world.name ~= "" then
343                                 local index = menudata.worldlist:get_raw_index(selected)
344                                 local delete_world_dlg = create_delete_world_dlg(world.name,index)
345                                 delete_world_dlg:set_parent(this)
346                                 this:hide()
347                                 delete_world_dlg:show()
348                                 mm_game_theme.update("singleplayer",current_game())
349                         end
350                 end
351
352                 return true
353         end
354
355         if fields["world_configure"] ~= nil then
356                 local selected = core.get_textlist_index("sp_worlds")
357                 if selected ~= nil then
358                         local configdialog =
359                                 create_configure_world_dlg(
360                                                 menudata.worldlist:get_raw_index(selected))
361
362                         if (configdialog ~= nil) then
363                                 configdialog:set_parent(this)
364                                 this:hide()
365                                 configdialog:show()
366                                 mm_game_theme.update("singleplayer",current_game())
367                         end
368                 end
369
370                 return true
371         end
372 end
373
374 local on_change
375 if enable_gamebar then
376         function on_change(type, old_tab, new_tab)
377                 if (type == "ENTER") then
378                         local game = current_game()
379                         if game then
380                                 apply_game(game)
381                         end
382
383                         singleplayer_refresh_gamebar()
384                         ui.find_by_name("game_button_bar"):show()
385                 else
386                         menudata.worldlist:set_filtercriteria(nil)
387                         local gamebar = ui.find_by_name("game_button_bar")
388                         if gamebar then
389                                 gamebar:hide()
390                         end
391                         core.set_topleft_text("")
392                         mm_game_theme.update(new_tab,nil)
393                 end
394         end
395 end
396
397 --------------------------------------------------------------------------------
398 return {
399         name = "local",
400         caption = fgettext("Start Game"),
401         cbf_formspec = get_formspec,
402         cbf_button_handler = main_button_handler,
403         on_change = on_change
404 }