]> git.lizzy.rs Git - worldedit.git/blob - worldedit_gui/init.lua
Added compatibility with my version of creative_inventory.
[worldedit.git] / worldedit_gui / init.lua
1 worldedit = worldedit or {}
2
3 --[[
4 Example:
5
6     worldedit.register_gui_function("worldedit_gui_hollow_cylinder", {
7         name = "Make Hollow Cylinder",
8         privs = {worldedit=true},
9         get_formspec = function(name) return "some formspec here" end,
10         on_select = function(name) print(name .. " clicked the button!") end,
11     })
12
13 Use `nil` for the `options` parameter to unregister the function associated with the given identifier.
14
15 Use `nil` for the `get_formspec` field to denote that the function does not have its own screen.
16
17 Use `nil` for the `privs` field to denote that no special privileges are required to use the function.
18
19 If the identifier is already registered to another function, it will be replaced by the new one.
20
21 The `on_select` function must not call `worldedit.show_page`
22 ]]
23
24 worldedit.pages = {} --mapping of identifiers to options
25 local identifiers = {} --ordered list of identifiers
26 worldedit.register_gui_function = function(identifier, options)
27         worldedit.pages[identifier] = options
28         table.insert(identifiers, identifier)
29 end
30
31 --[[
32 Example:
33
34     worldedit.register_gui_handler("worldedit_gui_hollow_cylinder", function(name, fields)
35         print(minetest.serialize(fields))
36     end)
37 ]]
38
39 worldedit.register_gui_handler = function(identifier, handler)
40         minetest.register_on_player_receive_fields(function(player, formname, fields)
41                 --ensure the form is not being exited since this is a duplicate message
42                 if fields.quit then
43                         return false
44                 end
45                 
46                 local name = player:get_player_name()
47                 
48                 --ensure the player has permission to perform the action
49                 local entry = worldedit.pages[identifier]
50                 if entry and minetest.check_player_privs(name, entry.privs or {}) then
51                         return handler(name, fields)
52                 end
53                 return false
54         end)
55 end
56
57 worldedit.get_formspec_header = function(identifier)
58         local entry = worldedit.pages[identifier] or {}
59         return "button[0,0;2,0.5;worldedit_gui;Back]" ..
60                 string.format("label[2,0;WorldEdit GUI > %s]", entry.name or "")
61 end
62
63 local get_formspec = function(name, identifier)
64         if worldedit.pages[identifier] then
65                 return worldedit.pages[identifier].get_formspec(name)
66         end
67         return worldedit.pages["worldedit_gui"].get_formspec(name) --default to showing main page if an unknown page is given
68 end
69
70 --implement worldedit.show_page(name, page) in different ways depending on the available APIs
71 if unified_inventory then --unified inventory installed
72         local old_func = worldedit.register_gui_function
73         worldedit.register_gui_function = function(identifier, options)
74                 old_func(identifier, options)
75                 unified_inventory.register_page(identifier, {get_formspec=function(player) return {formspec=options.get_formspec(player:get_player_name())} end})
76         end
77
78         unified_inventory.register_button("worldedit_gui", {
79                 type = "image",
80                 image = "inventory_plus_worldedit_gui.png",
81         })
82
83         minetest.register_on_player_receive_fields(function(player, formname, fields)
84                 local name = player:get_player_name()
85                 if fields.worldedit_gui then --main page
86                         worldedit.show_page(name, "worldedit_gui")
87                         return true
88                 elseif fields.worldedit_gui_exit then --return to original page
89                         unified_inventory.set_inventory_formspec(minetest.get_player_by_name(name), "craft")
90                         return true
91                 end
92                 return false
93         end)
94
95         worldedit.show_page = function(name, page)
96                 minetest.get_player_by_name(name):set_inventory_formspec(get_formspec(name, page))
97         end
98 elseif inventory_plus then --inventory++ installed
99         minetest.register_on_joinplayer(function(player)
100                 inventory_plus.register_button(player, "worldedit_gui", "WorldEdit")
101         end)
102
103         --show the form when the button is pressed and hide it when done
104         local gui_player_formspecs = {}
105         minetest.register_on_player_receive_fields(function(player, formname, fields)
106                 local name = player:get_player_name()
107                 if fields.worldedit_gui then --main page
108                         gui_player_formspecs[name] = player:get_inventory_formspec()
109                         worldedit.show_page(name, "worldedit_gui")
110                         return true
111                 elseif fields.worldedit_gui_exit then --return to original page
112                         if gui_player_formspecs[name] then
113                                 inventory_plus.set_inventory_formspec(player, gui_player_formspecs[name])
114                         end
115                         return true
116                 end
117                 return false
118         end)
119
120         worldedit.show_page = function(name, page)
121                 inventory_plus.set_inventory_formspec(minetest.get_player_by_name(name), get_formspec(name, page))
122         end
123 else --fallback button
124         local player_formspecs = {}
125
126         local update_main_formspec = function(name)
127                 local formspec = player_formspecs[name]
128                 if not formspec then
129                         return
130                 end
131                 local player = minetest.get_player_by_name(name)
132                 if (minetest.check_player_privs(name, {creative=true}) or minetest.setting_getbool("creative_mode")) and creative_inventory then --creative_inventory is active, add button to modified formspec
133                         formspec = player:get_inventory_formspec() .. "image_button[6,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
134                 else
135                         formspec = formspec .. "image_button[0,0;1,1;inventory_plus_worldedit_gui.png;worldedit_gui;]"
136                 end
137                 player:set_inventory_formspec(formspec)
138         end
139
140         minetest.register_on_joinplayer(function(player)
141                 local name = player:get_player_name()
142                 minetest.after(1, function()
143                         player_formspecs[name] = player:get_inventory_formspec()
144                         minetest.after(0.01, function()
145                                 update_main_formspec(name)
146                         end)
147                 end)
148         end)
149
150         minetest.register_on_leaveplayer(function(player)
151                 player_formspecs[player:get_player_name()] = nil
152         end)
153
154         local gui_player_formspecs = {}
155         minetest.register_on_player_receive_fields(function(player, formname, fields)
156                 local name = player:get_player_name()
157                 if fields.worldedit_gui then --main page
158                         gui_player_formspecs[name] = player:get_inventory_formspec()
159                         worldedit.show_page(name, "worldedit_gui")
160                         return true
161                 elseif fields.worldedit_gui_exit then --return to original page
162                         if gui_player_formspecs[name] then
163                                 player:set_inventory_formspec(gui_player_formspecs[name])
164                         end
165                         return true
166                 else --deal with creative_inventory setting the formspec on every single message
167                         minetest.after(0.01,function()
168                                 update_main_formspec(name)
169                         end)
170                         return false --continue processing in creative inventory
171                 end
172         end)
173
174         worldedit.show_page = function(name, page)
175                 local player = minetest.get_player_by_name(name)
176                 player:set_inventory_formspec(get_formspec(name, page))
177         end
178 end
179
180 worldedit.register_gui_function("worldedit_gui", {
181         name = "WorldEdit GUI",
182         get_formspec = function(name)
183                 --create a form with all the buttons arranged in a grid
184                 local buttons, x, y, index = {}, 0, 1, 0
185                 local width, height = 3, 0.8
186                 local columns = 5
187                 for i, identifier in pairs(identifiers) do
188                         if identifier ~= "worldedit_gui" then
189                                 local entry = worldedit.pages[identifier]
190                                 table.insert(buttons, string.format((entry.get_formspec and "button" or "button_exit") ..
191                                         "[%g,%g;%g,%g;%s;%s]", x, y, width, height, identifier, minetest.formspec_escape(entry.name)))
192
193                                 index, x = index + 1, x + width
194                                 if index == columns then --row is full
195                                         x, y = 0, y + height
196                                         index = 0
197                                 end
198                         end
199                 end
200                 if index == 0 then --empty row
201                         y = y - height
202                 end
203                 return string.format("size[%g,%g]", math.max(columns * width, 5), math.max(y + 0.5, 3)) ..
204                         "button[0,0;2,0.5;worldedit_gui_exit;Back]" ..
205                         "label[2,0;WorldEdit GUI]" ..
206                         table.concat(buttons)
207         end,
208 })
209
210 worldedit.register_gui_handler("worldedit_gui", function(name, fields)
211         for identifier, entry in pairs(worldedit.pages) do --check for WorldEdit GUI main formspec button selection
212                 if fields[identifier] and identifier ~= "worldedit_gui" then
213                         --ensure player has permission to perform action
214                         local has_privs, missing_privs = minetest.check_player_privs(name, entry.privs or {})
215                         if not has_privs then
216                                 worldedit.player_notify(name, "you are not allowed to use this function (missing privileges: " .. table.concat(missing_privs, ", ") .. ")")
217                                 return false
218                         end
219                         if entry.on_select then
220                                 entry.on_select(name)
221                         end
222                         if entry.get_formspec then
223                                 worldedit.show_page(name, identifier)
224                         end
225                         return true
226                 end
227         end
228         return false
229 end)
230
231 dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/functionality.lua")