4 creative - inventory code
6 Based on `creative` from minetest_game, MIT licensed code.
11 Copyright (C) 2012-2016 Perttu Ahola (celeron55) <celeron55@gmail.com>
12 Copyright (C) 2015-2016 Jean-Patrick G. (kilbith) <jeanpatrick.guerrero@gmail.com>
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,
34 local S
= minetest
.get_translator("creative")
35 local FE
= minetest
.formspec_escape
38 local player_inventory
= {}
42 local function creative_allowed(player_name
)
43 return boxes
.players_editing_boxes
[player_name
] or minetest
.check_player_privs(player_name
, "review")
47 function creative
.init_creative_inventory(player
)
48 local player_name
= player
:get_player_name()
49 player_inventory
[player_name
] = {
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)")
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)")
68 if to_list
~= "main" then
71 minetest
.log("error", "Client accesses inventory illegally (allow_move) (list)")
75 allow_put
= function(inv
, listname
, index
, stack
, player2
)
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)")
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)")
90 on_move
= function(inv
, from_list
, from_index
, to_list
, to_index
, count
, player2
)
92 on_put
= function(inv
, listname
, index
, stack
, player2
)
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")
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
]
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()
134 on_put
= function(inv
, listname
)
135 inv
:set_list(listname
, {})
138 trash
:set_size("main", 1)
140 creative
.formspec_add
= ""
142 function creative
.register_tab(name
, title
, items
)
143 sfinv
.register_page("creative:" .. name
, {
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())
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;]
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]
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)
183 on_enter
= function(self
, player
, context
)
184 local player_name
= player
:get_player_name()
185 local inv
= player_inventory
[player_name
]
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
]
195 if fields
.creative_clear
then
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
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
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
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
)
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
)