1 local S
= minetest
.get_translator("creative")
2 local F
= minetest
.formspec_escape
4 local player_inventory
= {}
5 local inventory_cache
= {}
7 local function init_creative_cache(items
)
8 inventory_cache
[items
] = {}
9 local i_cache
= inventory_cache
[items
]
11 for name
, def
in pairs(items
) do
12 if def
.groups
.not_in_creative_inventory
~= 1 and
13 def
.description
and def
.description
~= "" then
21 function creative
.init_creative_inventory(player
)
22 local player_name
= player
:get_player_name()
23 player_inventory
[player_name
] = {
29 minetest
.create_detached_inventory("creative_" .. player_name
, {
30 allow_move
= function(inv
, from_list
, from_index
, to_list
, to_index
, count
, player2
)
31 local name
= player2
and player2
:get_player_name() or ""
32 if not minetest
.is_creative_enabled(name
) or
33 to_list
== "main" then
38 allow_put
= function(inv
, listname
, index
, stack
, player2
)
41 allow_take
= function(inv
, listname
, index
, stack
, player2
)
42 local name
= player2
and player2
:get_player_name() or ""
43 if not minetest
.is_creative_enabled(name
) then
48 on_move
= function(inv
, from_list
, from_index
, to_list
, to_index
, count
, player2
)
50 on_take
= function(inv
, listname
, index
, stack
, player2
)
51 if stack
and stack
:get_count() > 0 then
52 minetest
.log("action", player_name
.. " takes " .. stack
:get_name().. " from creative inventory")
57 return player_inventory
[player_name
]
60 function creative
.update_creative_inventory(player_name
, tab_content
)
61 local creative_list
= {}
62 local inv
= player_inventory
[player_name
] or
63 creative
.init_creative_inventory(minetest
.get_player_by_name(player_name
))
64 local player_inv
= minetest
.get_inventory({type = "detached", name
= "creative_" .. player_name
})
66 local items
= inventory_cache
[tab_content
] or init_creative_cache(tab_content
)
68 for name
, def
in pairs(items
) do
69 if def
.name
:find(inv
.filter
, 1, true) or
70 (type(def
.description
) == "string" and def
.description
:lower():find(inv
.filter
, 1, true)) then
71 creative_list
[#creative_list
+1] = name
75 table.sort(creative_list
)
76 player_inv
:set_size("main", #creative_list
)
77 player_inv
:set_list("main", creative_list
)
78 inv
.size
= #creative_list
81 -- Create the trash field
82 local trash
= minetest
.create_detached_inventory("creative!trash", {
83 -- Allow the stack to be placed and remove it in on_put()
84 -- This allows the creative inventory to restore the stack
85 allow_put
= function(inv
, listname
, index
, stack
, player
)
86 return stack
:get_count()
88 on_put
= function(inv
, listname
)
89 inv
:set_list(listname
, {})
92 trash
:set_size("main", 1)
94 creative
.formspec_add
= ""
96 function creative
.register_tab(name
, title
, items
)
97 sfinv
.register_page("creative:" .. name
, {
99 is_in_nav
= function(self
, player
, context
)
100 return minetest
.is_creative_enabled(player
:get_player_name())
102 get
= function(self
, player
, context
)
103 local player_name
= player
:get_player_name()
104 creative
.update_creative_inventory(player_name
, items
)
105 local inv
= player_inventory
[player_name
]
106 local start_i
= inv
.start_i
or 0
107 local pagenum
= math
.floor(start_i
/ (3*8) + 1)
108 local pagemax
= math
.ceil(inv
.size
/ (3*8))
109 return sfinv
.make_formspec(player
, context
,
110 "label[6.2,3.35;" .. minetest
.colorize("#FFFF00", tostring(pagenum
)) .. " / " .. tostring(pagemax
) .. "]" ..
112 image[4.06,3.4;0.8,0.8;creative_trash_icon.png]
113 list[current_player;main;0,4.7;8,1;]
114 list[current_player;main;0,5.85;8,3;8]
115 list[detached:creative!trash;main;4,3.3;1,1;]
117 button[5.4,3.2;0.8,0.9;creative_prev;<]
118 button[7.25,3.2;0.8,0.9;creative_next;>]
119 button[2.1,3.4;0.8,0.5;creative_search;?]
120 button[2.75,3.4;0.8,0.5;creative_clear;X]
121 tooltip[creative_search;]]..F(S("Search"))..[[]
122 tooltip[creative_clear;]]..F(S("Reset"))..[[]
123 listring[current_player;main]
124 field_close_on_enter[creative_filter;false]
126 "field[0.3,3.5;2.2,1;creative_filter;;" .. minetest
.formspec_escape(inv
.filter
) .. "]" ..
127 "listring[detached:creative_" .. player_name
.. ";main]" ..
128 "list[detached:creative_" .. player_name
.. ";main;0,0;8,3;" .. tostring(start_i
) .. "]" ..
129 hades_gui
.gui_inventory_bg_img
130 .. creative
.formspec_add
, false)
132 on_enter
= function(self
, player
, context
)
133 local player_name
= player
:get_player_name()
134 local inv
= player_inventory
[player_name
]
139 on_player_receive_fields
= function(self
, player
, context
, fields
)
140 local player_name
= player
:get_player_name()
141 local inv
= player_inventory
[player_name
]
144 if fields
.creative_clear
then
147 creative
.update_creative_inventory(player_name
, items
)
148 sfinv
.set_player_inventory_formspec(player
, context
)
149 elseif fields
.creative_search
or
150 fields
.key_enter_field
== "creative_filter" then
152 inv
.filter
= fields
.creative_filter
:lower()
153 creative
.update_creative_inventory(player_name
, items
)
154 sfinv
.set_player_inventory_formspec(player
, context
)
155 elseif not fields
.quit
then
156 local start_i
= inv
.start_i
or 0
158 if fields
.creative_prev
then
159 start_i
= start_i
- 3*8
161 start_i
= inv
.size
- (inv
.size
% (3*8))
162 if inv
.size
== start_i
then
163 start_i
= math
.max(0, inv
.size
- (3*8))
166 elseif fields
.creative_next
then
167 start_i
= start_i
+ 3*8
168 if start_i
>= inv
.size
then
173 inv
.start_i
= start_i
174 sfinv
.set_player_inventory_formspec(player
, context
)
180 creative
.register_tab("all", S("All"), minetest
.registered_items
)
181 creative
.register_tab("nodes", S("Nodes"), minetest
.registered_nodes
)
182 creative
.register_tab("tools", S("Tools"), minetest
.registered_tools
)
183 creative
.register_tab("craftitems", S("Items"), minetest
.registered_craftitems
)
185 local old_homepage_name
= sfinv
.get_homepage_name
186 function sfinv
.get_homepage_name(player
)
187 if minetest
.is_creative_enabled(player
:get_player_name()) then
188 return "creative:all"
190 return old_homepage_name(player
)