Avoid unsafe `not` before condition.
[insidethebox.git] / mods / creative / init.lua
blob7bf6d26a57c51ad475697a792d11c00871948eb3
2 --[[
4 creative - inventory code
6 Based on `creative` from minetest_game, MIT licensed code.
7 Original work license:
9 ```
10 The MIT License (MIT)
11 Copyright (C) 2012-2016 Perttu Ahola (celeron55) <celeron55@gmail.com>
12 Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
13 ```
15 ITB (insidethebox) minetest game - Copyright (C) 2017-2018 sofar & nore
17 This library is free software; you can redistribute it and/or
18 modify it under the terms of the GNU Lesser General Public License
19 as published by the Free Software Foundation; either version 2.1
20 of the License, or (at your option) any later version.
22 This library is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
25 Lesser General Public License for more details.
27 You should have received a copy of the GNU Lesser General Public
28 License along with this library; if not, write to the Free
29 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
30 MA 02111-1307 USA
32 ]]--
34 local S = minetest.get_translator("creative")
35 local FE = minetest.formspec_escape
37 creative = {}
38 local player_inventory = {}
40 local admin = {}
42 local function creative_allowed(player_name)
43 return boxes.players_editing_boxes[player_name] or minetest.check_player_privs(player_name, "review")
45 end
47 function creative.init_creative_inventory(player)
48 local player_name = player:get_player_name()
49 player_inventory[player_name] = {
50 size = 0,
51 filter = "",
52 start_i = 0
55 minetest.create_detached_inventory("creative_" .. player_name, {
56 allow_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
57 if not player2 or player2:get_player_name() ~= player_name or not creative_allowed(player_name) then
58 minetest.log("error", "Client accesses inventory illegally (allow_move) (player)")
59 return 0
60 end
61 local stack1 = inv:get_stack(from_list, from_index)
62 local stack2 = inv:get_stack(to_list, to_index)
63 if (not stack1 or admin[stack1:get_name()] or not stack2 or admin[stack2:get_name()]) and
64 not minetest.check_player_privs(player_name, "review") then
65 minetest.log("error", "Client accesses inventory illegally (allow_move) (privs)")
66 return 0
67 end
68 if to_list ~= "main" then
69 return count
70 else
71 minetest.log("error", "Client accesses inventory illegally (allow_move) (list)")
72 return 0
73 end
74 end,
75 allow_put = function(inv, listname, index, stack, player2)
76 return 0
77 end,
78 allow_take = function(inv, listname, index, stack, player2)
79 if not player2 or player2:get_player_name() ~= player_name or not creative_allowed(player_name) then
80 minetest.log("error", "Client accesses inventory illegally (allow_take) (player)")
81 return 0
82 end
83 if (not stack or admin[stack:get_name()]) and
84 not minetest.check_player_privs(player_name, "review") then
85 minetest.log("error", "Client accesses inventory illegally (allow_take) (privs)")
86 return 0
87 end
88 return -1
89 end,
90 on_move = function(inv, from_list, from_index, to_list, to_index, count, player2)
91 end,
92 on_put = function(inv, listname, index, stack, player2)
93 end,
94 on_take = function(inv, listname, index, stack, player2)
95 if stack and stack:get_count() > 0 then
96 minetest.log("action", player_name .. " takes " .. stack:get_name().. " from creative inventory")
97 end
98 end,
99 }, player_name)
101 creative.update_creative_inventory(player_name, minetest.registered_items)
104 function creative.update_creative_inventory(player_name, tab_content)
105 local creative_list = {}
106 local player_inv = minetest.get_inventory({type = "detached", name = "creative_" .. player_name})
107 local inv = player_inventory[player_name]
108 if not inv then
109 creative.init_creative_inventory(minetest.get_player_by_name(player_name))
112 for name, def in pairs(tab_content) do
113 if not (def.groups and def.groups.not_in_creative_inventory == 1) and
114 def.description and def.description ~= "" and
115 (def.name:find(inv.filter, 1, true) or
116 def.description:lower():find(inv.filter, 1, true)) then
117 creative_list[#creative_list+1] = name
121 table.sort(creative_list)
122 player_inv:set_size("main", #creative_list)
123 player_inv:set_list("main", creative_list)
124 inv.size = #creative_list
127 -- Create the trash field
128 local trash = minetest.create_detached_inventory("creative_trash", {
129 -- Allow the stack to be placed and remove it in on_put()
130 -- This allows the creative inventory to restore the stack
131 allow_put = function(inv, listname, index, stack, player)
132 return stack:get_count()
133 end,
134 on_put = function(inv, listname)
135 inv:set_list(listname, {})
136 end,
138 trash:set_size("main", 1)
140 creative.formspec_add = ""
142 function creative.register_tab(name, title, items)
143 sfinv.register_page("creative:" .. name, {
144 title = title,
145 is_in_nav = function(self, player, context)
146 if name == "admin" then
147 return minetest.check_player_privs(player, "review")
149 return creative_allowed(player:get_player_name())
150 end,
151 get = function(self, player, context)
152 local player_name = player:get_player_name()
153 creative.update_creative_inventory(player_name, items)
154 local inv = player_inventory[player_name]
155 local start_i = inv.start_i or 0
156 local pagenum = math.floor(start_i / (3*8) + 1)
157 local pagemax = math.ceil(inv.size / (3*8))
158 return sfinv.make_formspec(player, context,
159 "label[6.2,3.35;" .. minetest.colorize("#FFFF00", tostring(pagenum)) .. " / " .. tostring(pagemax) .. "]" ..
161 image[4.06,3.4;0.8,0.8;creative_trash_icon.png]
162 listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
163 list[current_player;main;0,4.7;8,1;]
164 list[current_player;main;0,5.85;8,3;8]
165 list[detached:creative_trash;main;4,3.3;1,1;]
166 listring[]
167 button[5.4,3.2;0.8,0.9;creative_prev;]]..FE(S("<"))..[[]
168 button[7.25,3.2;0.8,0.9;creative_next;]]..FE(S(">"))..[[]
169 button[2.1,3.4;0.8,0.5;creative_search;]]..FE(S("?"))..[[]
170 button[2.75,3.4;0.8,0.5;creative_clear;]]..FE(S("X"))..[[]
171 tooltip[creative_search;]]..FE(S("Search"))..[[]
172 tooltip[creative_clear;]]..FE(S("Reset"))..[[]
173 listring[current_player;main]
174 field_close_on_enter[creative_filter;false]
175 ]] ..
176 "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest.formspec_escape(inv.filter) .. "]" ..
177 "listring[detached:creative_" .. player_name .. ";main]" ..
178 "list[detached:creative_" .. player_name .. ";main;0,0;8,3;" .. tostring(start_i) .. "]" ..
179 sfinv.get_hotbar_bg(0,4.7) ..
180 sfinv.style.gui_bg .. sfinv.style.gui_bg_img .. sfinv.style.gui_slots
181 .. creative.formspec_add, false)
182 end,
183 on_enter = function(self, player, context)
184 local player_name = player:get_player_name()
185 local inv = player_inventory[player_name]
186 if inv then
187 inv.start_i = 0
189 end,
190 on_player_receive_fields = function(self, player, context, fields)
191 local player_name = player:get_player_name()
192 local inv = player_inventory[player_name]
193 assert(inv)
195 if fields.creative_clear then
196 inv.start_i = 0
197 inv.filter = ""
198 creative.update_creative_inventory(player_name, items)
199 sfinv.set_player_inventory_formspec(player, context)
200 elseif fields.creative_search or
201 fields.key_enter_field == "creative_filter" then
202 inv.start_i = 0
203 inv.filter = fields.creative_filter:lower()
204 creative.update_creative_inventory(player_name, items)
205 sfinv.set_player_inventory_formspec(player, context)
206 elseif not fields.quit then
207 local start_i = inv.start_i or 0
209 if fields.creative_prev then
210 start_i = start_i - 3*8
211 if start_i < 0 then
212 start_i = inv.size - (inv.size % (3*8))
213 if inv.size == start_i then
214 start_i = math.max(0, inv.size - (3*8))
217 elseif fields.creative_next then
218 start_i = start_i + 3*8
219 if start_i >= inv.size then
220 start_i = 0
224 inv.start_i = start_i
225 sfinv.set_player_inventory_formspec(player, context)
231 minetest.register_on_joinplayer(function(player)
232 creative.init_creative_inventory(player)
233 end)
235 -- custom inventory lists for nodes and tools.
236 local nodes = table.copy(minetest.registered_nodes)
237 nodes["boxes:creator_teleport"] = nil
238 nodes["boxes:enter_teleport"] = nil
239 nodes["boxes:exit_teleport"] = nil
240 nodes["boxes:lobby_teleport"] = nil
241 nodes["nodes:barrier"] = nil
242 nodes["doors:door_wood"] = table.copy(minetest.registered_items["doors:door_wood"])
243 nodes["doors:door_wood"].groups = {}
244 nodes["doors:door_steel"] = table.copy(minetest.registered_items["doors:door_steel"])
245 nodes["doors:door_steel"].groups = {}
246 creative.register_tab("nodes", S("Nodes"), nodes)
248 local tools = table.copy(minetest.registered_tools)
249 tools["tools:admin"] = nil
250 tools["inspector:inspector"] = nil
251 tools["boxes:set_door"] = table.copy(minetest.registered_items["boxes:set_door"])
252 tools["tools:shovel"] = table.copy(minetest.registered_items["tools:shovel"])
253 tools["tools:axe"] = table.copy(minetest.registered_items["tools:axe"])
254 tools["tools:pickaxe"] = table.copy(minetest.registered_items["tools:pickaxe"])
255 tools["tools:sword"] = table.copy(minetest.registered_items["tools:sword"])
256 tools["tools:flint_and_steel"] = table.copy(minetest.registered_items["tools:flint_and_steel"])
257 creative.register_tab("tools", S("Tools"), tools)
259 admin["boxes:creator_teleport"] = table.copy(minetest.registered_items["boxes:creator_teleport"])
260 admin["boxes:enter_teleport"] = table.copy(minetest.registered_items["boxes:enter_teleport"])
261 admin["boxes:exit_teleport"] = table.copy(minetest.registered_items["boxes:exit_teleport"])
262 admin["boxes:lobby_teleport"] = table.copy(minetest.registered_items["boxes:lobby_teleport"])
263 admin["nodes:barrier"] = table.copy(minetest.registered_items["nodes:barrier"])
264 admin["nodes:barrier"].groups = {}
265 admin["nodes:marbleb"] = table.copy(minetest.registered_items["nodes:marbleb"])
266 admin["nodes:marbleb"].groups = {}
267 admin["nodes:bronzeb"] = table.copy(minetest.registered_items["nodes:bronzeb"])
268 admin["nodes:bronzeb"].groups = {}
269 admin["tools:admin"] = table.copy(minetest.registered_items["tools:admin"])
270 admin["inspector:inspector"] = table.copy(minetest.registered_items["inspector:inspector"])
271 admin["boxes:nexus_large"] = table.copy(minetest.registered_items["boxes:nexus_large"])
272 admin["boxes:nexus_large"].groups = {}
273 creative.register_tab("admin", S("Admin Items"), admin)