Creative inventory buttons

master
stujones11 2019-05-31 21:11:39 +01:00
parent f29ed3e20e
commit 67795ccf0c
1 changed files with 98 additions and 70 deletions

View File

@ -90,38 +90,9 @@ local function init_creative_inventory(player_name)
player_inventory[player_name] = {
size = 0,
filter = "",
start_i = 0
start_i = 0,
list = {},
}
minetest.create_detached_inventory("creative_" .. player_name, {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
local name = player and player:get_player_name() or ""
if not creative.is_enabled_for(name) or
to_list == "main" then
return 0
end
return count
end,
allow_put = function(inv, listname, index, stack, player)
return 0
end,
allow_take = function(inv, listname, index, stack, player)
local name = player and player:get_player_name() or ""
if not creative.is_enabled_for(name) then
return 0
end
return -1
end,
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
end,
on_take = function(inv, listname, index, stack, player)
if stack and stack:get_count() > 0 then
minetest.log("action", player_name.." takes "..
stack:get_name().." from creative inventory")
end
end,
}, player_name)
return player_inventory[player_name]
end
@ -130,53 +101,53 @@ local function update_creative_inventory(player_name, tab_name)
if not player or not player:is_player() then
return
end
local creative_list = {}
local inv = player_inventory[player_name] or
init_creative_inventory(player_name)
local player_inv = minetest.get_inventory({type="detached",
name="creative_"..player_name})
if not player_inv then
player_inventory[player_name] = nil
return
local creative_list = inv.list
for k in pairs (creative_list) do
creative_list[k] = nil
end
local items = inventory_cache[tab_name] or {}
local filter = tab_name == "all" and inv.filter or ""
for name, description in pairs(items) do
if name:find(inv.filter, 1, true) or
description:lower():find(inv.filter, 1, true) then
creative_list[#creative_list+1] = name
description:lower():find(filter, 1, true) then
creative_list[#creative_list + 1] = name
end
end
table.sort(creative_list)
player_inv:set_size("main", #creative_list)
player_inv:set_list("main", creative_list)
inv.size = #creative_list
inv.filter = filter
end
-- Create the trash field
local trash = minetest.create_detached_inventory("creative_trash", {
-- Allow the stack to be placed and remove it in on_put()
-- This allows the creative inventory to restore the stack
allow_put = function(inv, listname, index, stack, player)
return stack:get_count()
end,
on_put = function(inv, listname)
inv:set_list(listname, {})
end,
})
trash:set_size("main", 1)
local function get_button_formspec(player_name, start_i)
local buttons = ""
local inv = player_inventory[player_name] or
init_creative_inventory(player_name)
local creative_list = inv.list or {}
local i = start_i + 1
for y = 0, 4 do
for x = 0, 8 do
local item = creative_list[i]
if not item then
return buttons
end
buttons = buttons.."item_image_button["..
(x + 0.01)..","..(y + 1.67)..";1,1;"..item..";"..item..";]"
i = i + 1
end
end
return buttons
end
local function get_creative_formspec(player_name, start_i, pagenum, page, pagemax)
page = page or "all"
pagenum = math.floor(pagenum) or 1
pagemax = (pagemax and pagemax ~= 0) and pagemax or 1
local slider_height = 4 / pagemax - 0.04
local slider_pos = 4 / pagemax * (pagenum - 1) + 2.14
local main_list = "list[detached:creative_" .. player_name ..
";main;0.02,1.68;9,5;"..tostring(start_i).."]"
local name = "all"
if page ~= nil then name = page end
if name == "inv" then
local main_list = get_button_formspec(player_name, start_i)
if page == "inv" then
main_list = "image[-0.2,1.6;11.35,2.33;creative_bg.png]"..
"list[current_player;main;0.02,3.68;9,3;9]"
if has_armor then
@ -191,7 +162,7 @@ local function get_creative_formspec(player_name, start_i, pagenum, page, pagema
"background[-0.2,-0.26;11.55,8.49;inventory_creative.png]"..
sfinv.gui_bg..
sfinv.listcolors..
"label[-5,-5;"..name.."]"..
"label[-5,-5;"..page.."]"..
"image_button[-0.16,-0.15;1,1;"..bg["blocks"]..";build;;;false]".. --build blocks
"image_button[0.87,-0.15;1,1;"..bg["deco"]..";deco;;;false]".. --decoration blocks
"image_button[1.92,-0.15;1,1;"..bg["mese"]..";mese;;;false]".. --bluestone
@ -206,18 +177,19 @@ local function get_creative_formspec(player_name, start_i, pagenum, page, pagema
"image_button[10.25,7.11;1,1;"..bg["inv"]..";inv;;;false]".. --inventory
"image_button_exit[10.3,2.5;1,1;creative_home_set.png;sethome_set;;true;true;]"..
"image_button_exit[10.3,3.5;1,1;creative_home_go.png;sethome_go;;true;true;]"..
"image[0,0.95;5,0.75;fnt_"..name..".png]"..
"image[0,0.95;5,0.75;fnt_"..page..".png]"..
"image_button[9.145,1.65;0.81,0.6;creative_up.png;creative_prev;]"..
"image_button[9.145,6.08;0.81,0.6;creative_down.png;creative_next;]"..
"list[current_player;main;0.02,6.93;9,1;]"..main_list..
"list[detached:creative_trash;main;9.03,6.94;1,1;]"..
"image["..ofs_tab[name]..";1.45,1.45;creative_active.png"..rot[name].."]"..
"image["..ofs_img[name]..";1,1;"..bg[name].."]"..
"image["..ofs_tab[page]..";1.45,1.45;creative_active.png"..rot[page].."]"..
"image["..ofs_img[page]..";1,1;"..bg[page].."]"..
"image[9.165," .. tostring(slider_pos) .. ";0.7,"..tostring(slider_height) .. ";creative_slider.png]"
if name == "all" then
if page == "all" then
local inv = player_inventory[player_name] or {}
local filter = inv.filter or ""
formspec = formspec .. "field_close_on_enter[search;false]"..
"field[5.31,1.27;4.0,0.75;search;;]"..
"field[5.31,1.27;4.0,0.75;search;;"..filter.."]"..
"image_button[9.14,0.93;0.81,0.82;creative_search.png;creative_search;;;false]"
end
if pagenum ~= nil then
@ -226,6 +198,42 @@ local function get_creative_formspec(player_name, start_i, pagenum, page, pagema
return formspec
end
local function add_to_player_inventory(player, item)
if not player or not player:is_player() or not item then
return
end
local inv = player:get_inventory()
if not inv then
return
end
local def = minetest.registered_items[item]
if not def or (def.groups and def.groups.not_in_creative_inventory == 1) then
return
end
local empty_slot = nil
local list = inv:get_list("main")
if list and #list > 8 then
for i = 1, 9 do
local stack = list[i]
if stack then
if not empty_slot and stack:get_count() == 0 then
empty_slot = i
elseif stack:get_name() == item and
stack:get_free_space() > 0 then
stack:add_item(item)
inv:set_stack("main", i, stack)
return
end
end
end
if empty_slot then
local stack = list[empty_slot]
stack:add_item(item)
inv:set_stack("main", empty_slot, stack)
end
end
end
local function register_tab(name, title, group)
init_creative_cache(name, group)
sfinv.register_page("creative:" .. name, {
@ -257,8 +265,15 @@ local function register_tab(name, title, group)
if not inv then
return
end
inv.filter = ""
if creative.is_enabled_for(player_name) then
for field, _ in pairs(fields) do
if field:find(":") then
add_to_player_inventory(player, field)
return
end
end
end
inv.filter = fields.search and fields.search:lower() or ""
if fields.build then
sfinv.set_page(player, "creative:blocks")
elseif fields.deco then
@ -287,7 +302,7 @@ local function register_tab(name, title, group)
(fields.creative_search or
fields.key_enter_field == "search") then
inv.start_i = 0
inv.filter = fields.search:lower()
--inv.filter = fields.search:lower()
update_creative_inventory(player_name, name)
sfinv.set_player_inventory_formspec(player, context)
elseif not fields.quit then
@ -336,3 +351,16 @@ function sfinv.get_homepage_name(player)
return old_homepage_name(player)
end
end
-- Create the trash field
local trash = minetest.create_detached_inventory("creative_trash", {
-- Allow the stack to be placed and remove it in on_put()
-- This allows the creative inventory to restore the stack
allow_put = function(inv, listname, index, stack, player)
return stack:get_count()
end,
on_put = function(inv, listname)
inv:set_list(listname, {})
end,
})
trash:set_size("main", 1)