Add hint mod code - MT refuses to load mods without `init.lua`
[insidethebox.git] / mods / menu / init.lua
blobba0076c88cf91a118f0817a5b69d77ef1b49c801
2 --[[
4 ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public License
8 as published by the Free Software Foundation; either version 2.1
9 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 MA 02111-1307 USA
21 ]]--
23 --[[
25 game menu options for use with sfinv
27 --]]
29 local S = minetest.get_translator("menu")
30 local FE = minetest.formspec_escape
32 local function toggle_music(player)
33 local pmeta = player:get_meta()
34 local m = pmeta:get_string("music")
35 if not m or m == "1" then
36 music.stop(player)
37 m = "0"
38 minetest.chat_send_player(player:get_player_name(), S("Music is now disabled."))
39 else
40 m = "1"
41 minetest.chat_send_player(player:get_player_name(), S("Music is now enabled. Music playback will start later."))
42 end
43 pmeta:set_string("music", m)
44 end
46 sfinv.register_page("menu:lobby", {
47 title = S("Game"),
48 is_in_nav = function(self, player, context)
49 local name = player:get_player_name()
50 return not boxes.players_editing_boxes[name] and not boxes.players_in_boxes[name]
51 end,
52 get = function(self, player, context)
53 return sfinv.make_formspec(player, context,
54 "button[0.5,0.5;4,0.6;music;"..FE(S("Toggle music")).."]" ..
55 sfinv.get_hotbar_bg(0,4.7) ..
56 sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
57 .. creative.formspec_add, true)
58 end,
59 on_player_receive_fields = function(self, player, context, fields)
60 if fields.music then
61 toggle_music(player)
62 end
63 return
64 end,
67 local function callback_erase(player, fields, context)
68 local name = player:get_player_name()
69 if fields.btn_cancel or fields.quit then
70 return true
71 end
72 if not fields.btn_erase or
73 context ~= tonumber(fields.confirm) or
74 not boxes.players_editing_boxes[name] then
75 return true
76 end
78 -- wipe the box
79 local box = boxes.players_editing_boxes[name]
80 minetest.log("action", name .. " erases all content of box " .. box.box_id)
82 local minp = vector.add(box.minp, 1)
83 local maxp = vector.add(box.maxp, -1)
85 -- wipe nodes with meta separately
86 for _, p in ipairs(minetest.find_nodes_with_meta(minp, maxp)) do
87 minetest.remove_node(p)
88 end
90 local cid_air = minetest.get_content_id("air")
92 local vm = minetest.get_voxel_manip(minp, maxp)
93 local emin, emax = vm:get_emerged_area()
94 local va = VoxelArea:new{MinEdge=emin,MaxEdge=emax}
95 local vmdata = vm:get_data()
96 local param2 = vm:get_param2_data()
98 for z = minp.z, maxp.z do
99 for y = minp.y, maxp.y do
100 local index = va:index(minp.x, y, z)
101 for x = minp.x, maxp.x do
102 vmdata[index] = cid_air
103 param2[index] = 0
104 index = index + 1
108 vm:set_data(vmdata)
109 vm:set_param2_data(param2)
110 vm:update_liquids()
111 vm:write_to_map()
112 vm:update_map()
113 minetest.after(0.1, minetest.fix_light, minp, maxp)
115 -- reset pedestal number, build time
116 box.start_edit_time = minetest.get_gametime()
117 box.num_items = 0
118 local bmeta = db.box_get_meta(box.box_id)
119 bmeta.meta.num_items = 0
120 bmeta.meta.build_time = 0
121 db.box_set_meta(box.box_id, bmeta)
123 return true
126 local function callback_landscape(player, fields, context)
127 local name = player:get_player_name()
128 if fields.btn_cancel or fields.quit then
129 return true
131 if not fields.btn_landscape or
132 context ~= tonumber(fields.confirm) or
133 not boxes.players_editing_boxes[name] then
134 return true
137 -- landscape the box
138 local box = boxes.players_editing_boxes[name]
139 minetest.log("action", name .. " landscapes box " .. box.box_id)
141 local minp = vector.add(box.minp, 1)
142 local maxp = vector.add(box.maxp, -1)
144 local vm = minetest.get_voxel_manip(minp, maxp)
145 local emin, emax = vm:get_emerged_area()
146 local va = VoxelArea:new{MinEdge=emin,MaxEdge=emax}
147 local vmdata = vm:get_data()
148 local param2 = vm:get_param2_data()
150 local cursor = 8
151 local stack
153 for y = minp.y, maxp.y do
154 local inv = player:get_inventory()
155 while not stack or stack:is_empty() and cursor > 1 do
156 stack = inv:get_stack("landscape", cursor)
157 cursor = cursor - 1
159 if not stack:is_empty() then
160 local item = stack:take_item()
161 local iname = item:get_name()
162 if iname ~= "torches:torch" and minetest.registered_nodes[iname] then
163 local cid = minetest.get_content_id(iname)
164 for z = minp.z, maxp.z do
165 local index = va:index(minp.x, y, z)
166 for x = minp.x, maxp.x do
167 vmdata[index] = cid
168 param2[index] = 0
169 index = index + 1
176 vm:set_data(vmdata)
177 vm:set_param2_data(param2)
178 vm:update_liquids()
179 vm:write_to_map()
180 vm:update_map()
181 minetest.after(0.1, minetest.fix_light, minp, maxp)
183 -- reset pedestal number, build time
184 box.start_edit_time = minetest.get_gametime()
185 box.num_items = 0
186 local bmeta = db.box_get_meta(box.box_id)
187 bmeta.meta.num_items = 0
188 bmeta.meta.build_time = 0
189 db.box_set_meta(box.box_id, bmeta)
191 return true
194 sfinv.register_page("menu:edit", {
195 title = S("Game"),
196 is_in_nav = function(self, player, context)
197 local name = player:get_player_name()
198 return boxes.players_editing_boxes[name]
199 end,
200 get = function(self, player, context)
201 local name = player:get_player_name()
202 local box = boxes.players_editing_boxes[name]
203 local name_edit = ""
204 if box and box.box_name ~= nil then
205 name_edit = "field[0.8,2.6;4,0.6;box_name;"..FE(S("Box name"))..";" ..
206 minetest.formspec_escape(box.box_name) ..
209 local skyboxnr = 0
210 if box and box.skybox then
211 skyboxnr = box.skybox
213 local skybox =
214 "label[0.5,2.9;"..FE(S("Sky box:")).."]" ..
215 "dropdown[0.5,3.3;4.0;skybox;" ..
216 "0 - " .. FE(S("off")).."," ..
217 "1 - " .. FE(S("Dark and Stormy")).."," ..
218 "2 - " .. FE(S("Cloudy with light rays")).."," ..
219 "3 - " .. FE(S("Full Moon")).."," ..
220 "4 - " .. FE(S("Sunset")).."," ..
221 "5 - " .. FE(S("Thick clouds over water")).."," ..
222 "6 - " .. FE(S("Tropical sunny day")) ..
223 ";" .. tostring(skyboxnr + 1) .."]"
224 return sfinv.make_formspec(player, context,
225 "button[0.5,0.5;4,0.6;save;"..FE(S("Save this box")).."]" ..
226 "button[0.5,1.3;4,0.6;stopedit;"..FE(S("Stop editing this box")).."]" ..
227 name_edit ..
228 skybox ..
229 "button[0.5,4.2;4,0.6;erase;"..FE(S("Wipe everything in this box")).."]" ..
230 "button[0.5,5.0;4,0.6;landscape;"..FE(S("Landscape this box")).."]" ..
231 "button[0.5,5.8;4,0.6;music;"..FE(S("Toggle music")).."]" ..
232 sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots, false)
233 end,
234 on_player_receive_fields = function(self, player, context, fields)
235 if fields.stopedit then
236 minetest.close_formspec(player:get_player_name(), "")
237 boxes.save_edit(player)
238 boxes.stop_edit(player)
239 music.stop(player)
240 players.return_to_lobby(player)
241 return
243 -- don't elseif here - if text fields change we want to save them anyway.
244 if fields.save then
245 minetest.close_formspec(player:get_player_name(), "")
246 boxes.save_edit(player)
248 if fields.skybox then
249 local number = tonumber(fields.skybox:sub(1,1))
250 skybox.set(player, number)
251 boxes.players_editing_boxes[player:get_player_name()].skybox = number
253 if fields.box_name then
254 boxes.players_editing_boxes[player:get_player_name()].box_name = fields.box_name
255 sfinv.set_player_inventory_formspec(player)
257 if fields.erase then
258 local name = player:get_player_name()
259 local token = math.random(10000, 99999)
260 fsc.show(name,
261 "size[10,7]" ..
262 -- TODO: Change to multi-line label
263 "textlist[0.5,0.5;8.7,2.0;restettext;" ..
264 -- TODO: Make translatable
265 "Erasing the content is irreversible\\, and can not," ..
266 "be undone. Are you sure you want to continue?,," ..
267 "If you are sure\\, then type \"" .. token .. "\" in this " ..
268 "text box\\,and press \"Erase Everything\".;0;0]" ..
269 "field[4.0,3.5;3.0,1.5;confirm;;]" ..
270 "button[0.6,5.5;4.4,1.5;btn_cancel;"..FE(S("Cancel")).."]" ..
271 "button[5.0,5.5;4.4,1.5;btn_erase;"..FE(S("Erase everything")).."]",
272 token,
273 callback_erase
276 if fields.landscape then
277 local name = player:get_player_name()
278 local token = math.random(10000, 99999)
279 local inv = minetest.get_inventory({type="player", name = name})
280 inv:set_size("landscape", 10)
281 fsc.show(name,
282 "size[10,10]" ..
283 "list[current_player:landscape;landscape;0.2,0;1,8;]" ..
284 "list[current_player;main;1.6,0;8,1;]" ..
285 "listring[]" ..
286 "list[current_player;main;1.6,1.1;8,3;8]" ..
287 -- TODO: Make translatable, use multi-line label
288 "label[1.6,5;Drop nodes to the left from your inventory to create base layers for]" ..
289 "label[1.6,5.4;your box with these nodes. The stack size determines the thickness]" ..
290 "label[1.6,5.8;of the layers. Empty slots are omitted. Put torches in to leave]" ..
291 "label[1.6,6.2;multiple layers empty. The blocks in those layers will not be removed.]" ..
292 "label[1.6,7.6;Put the code \\\"" .. token .. "\\\" in the box here:]" ..
293 "field[6.4,7.4;3.0,1.5;confirm;;]" ..
294 "button[1.4,8.8;4,1.5;btn_cancel;"..FE(S("Cancel")).."]" ..
295 "button[5.4,8.8;4,1.5;btn_landscape;"..FE(S("Landscape this box")).."]",
296 token,
297 callback_landscape
300 if fields.music then
301 toggle_music(player)
303 end,
307 sfinv.register_page("menu:play", {
308 title = "Game",
309 is_in_nav = function(self, player, context)
310 local name = player:get_player_name()
311 return boxes.players_in_boxes[name]
312 end,
313 get = function(self, player, context)
314 local name = player:get_player_name()
315 local box = boxes.players_in_boxes[name]
316 local bmeta = db.box_get_meta(box.box_id)
317 local label = "label[0.5,0.5;"..FE(S("You are in box @1: \"@2\" by @3",
318 box.box_id, bmeta.meta.box_name, bmeta.meta.builder)) .. "]"
319 local leave_btn = "button[0.5,2.1;4,0.6;leave;"..FE(S("Leave this box")).."]"
320 if conf.tutorial.required then
321 local pmeta = player:get_meta()
322 if pmeta:get_string("tutorial_completed") ~= "1" then
323 leave_btn = ""
326 return sfinv.make_formspec(player, context,
327 label ..
328 leave_btn ..
329 "button[0.5,1.3;4,0.6;music;"..FE(S("Toggle music")).."]" ..
330 sfinv.get_hotbar_bg(0,4.7) ..
331 sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
332 .. creative.formspec_add, true)
333 end,
334 on_player_receive_fields = function(self, player, context, fields)
335 if fields.leave then
336 music.stop(player)
337 minetest.close_formspec(player:get_player_name(), "")
338 boxes.close_box(player)
339 players.return_to_lobby(player)
341 if fields.music then
342 toggle_music(player)
344 end,