262 lines
7.4 KiB
Lua
262 lines
7.4 KiB
Lua
local F = minetest.formspec_escape
|
|
local S = minetest.get_translator("getitem")
|
|
|
|
local detached_inventories = {}
|
|
local current_pages = {}
|
|
|
|
local SLOTS_W = 10
|
|
local SLOTS_H = 5
|
|
local SLOTS = SLOTS_W * SLOTS_H
|
|
|
|
local function allow_check(player, msg_disallowed)
|
|
if player and player:is_player() then
|
|
local name = player:get_player_name()
|
|
if minetest.check_player_privs(name, "give") then
|
|
return -1
|
|
else
|
|
minetest.chat_send_player(name, msg_disallowed)
|
|
minetest.close_formspec(name, "getitem:getitem")
|
|
return 0
|
|
end
|
|
else
|
|
return -1
|
|
end
|
|
end
|
|
|
|
-- Create detached inventories
|
|
local function add_detached_inventories(player)
|
|
local name = player:get_player_name()
|
|
local inv_items = minetest.create_detached_inventory("getitem_items_"..name, {
|
|
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
return 0
|
|
end,
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
return 0
|
|
end,
|
|
allow_take = function(inv, listname, index, stack, player)
|
|
return allow_check(player, S("You can't take items ('give' privilege required)."))
|
|
end,
|
|
}, name)
|
|
local inv_trash = minetest.create_detached_inventory("getitem_trash_"..name, {
|
|
allow_take = function(inv, listname, index, stack, player)
|
|
return 0
|
|
end,
|
|
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
return 0
|
|
end,
|
|
allow_put = function(inv, listname, index, stack, player)
|
|
local ret = allow_check(player, S("You can't trash items ('give' privilege required)."))
|
|
if ret == -1 then
|
|
return stack:get_count()
|
|
else
|
|
return 0
|
|
end
|
|
end,
|
|
on_put = function(inv, listname, index, stack, player)
|
|
inv:set_list(listname, {})
|
|
end,
|
|
}, name)
|
|
inv_trash:set_size("main", 1)
|
|
detached_inventories[name] = { items = inv_items, trash = inv_trash }
|
|
end
|
|
|
|
local max_page = 1
|
|
|
|
local function get_formspec(page, name)
|
|
local start = 0 + (page-1)*SLOTS
|
|
if not name then
|
|
return ""
|
|
end
|
|
local player = minetest.get_player_by_name(name)
|
|
local playerinvsize = player:get_inventory():get_size("main")
|
|
local hotbarsize = player:hud_get_hotbar_itemcount()
|
|
local pinv_w, pinv_h, pinv_x
|
|
pinv_w = hotbarsize
|
|
pinv_h = math.ceil(playerinvsize / pinv_w)
|
|
pinv_w = math.min(pinv_w, 10)
|
|
pinv_h = math.min(pinv_w, 4)
|
|
pinv_x = 0
|
|
if pinv_w < 9 then
|
|
pinv_x = 1
|
|
end
|
|
|
|
local pagestr = ""
|
|
if max_page > 1 then
|
|
pagestr = "button[0,5;1,1;getitem_prev;"..F(S("<")).."]"..
|
|
"button[1,5;1,1;getitem_next;"..F(S(">")).."]"..
|
|
"label[2,5;"..F(S("Page: @1/@2", page, max_page)).."]"
|
|
end
|
|
|
|
return "size[10,10]"..
|
|
"list[detached:getitem_items_"..name..";main;0,0;"..SLOTS_W..","..SLOTS_H..";"..start.."]"..
|
|
"list[current_player;main;"..pinv_x..",6;"..pinv_w..","..pinv_h..";]" ..
|
|
"label[8,5;"..F(S("Trash:")).."]" ..
|
|
"list[detached:getitem_trash_"..name..";main;9,5;1,1]" ..
|
|
pagestr ..
|
|
"listring[detached:getitem_items_"..name..";main]"..
|
|
"listring[current_player;main]"..
|
|
"listring[detached:getitem_trash_"..name..";main]"
|
|
end
|
|
|
|
local show_formspec = function(name)
|
|
if not minetest.check_player_privs(name, "give") then
|
|
minetest.chat_send_player(name, S("You need to have the 'give' privilege to use this."))
|
|
minetest.close_formspec(name, "getitem:getitem")
|
|
return false
|
|
end
|
|
local page = current_pages[name]
|
|
local form = get_formspec(page, name)
|
|
minetest.show_formspec(name, "getitem:getitem", form)
|
|
return true
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname == "getitem:getitem" then
|
|
local name = player:get_player_name()
|
|
if not minetest.check_player_privs(name, "give") then
|
|
minetest.chat_send_player(name, S("You need to have the 'give' privilege to use this."))
|
|
minetest.close_formspec(name, "getitem:getitem")
|
|
return
|
|
end
|
|
local page = current_pages[name]
|
|
local old_page = page
|
|
if fields.getitem_next then
|
|
page = page + 1
|
|
elseif fields.getitem_prev then
|
|
page = page - 1
|
|
else
|
|
return
|
|
end
|
|
if page < 1 then
|
|
page = 1
|
|
end
|
|
if page > max_page then
|
|
page = max_page
|
|
end
|
|
if page ~= old_page then
|
|
current_pages[name] = page
|
|
show_formspec(name)
|
|
end
|
|
end
|
|
end)
|
|
|
|
minetest.register_chatcommand("giveitem", {
|
|
description = S("Show a dialog to receive all items"),
|
|
param = "",
|
|
privs = { give = true },
|
|
func = function(name, param)
|
|
return show_formspec(name)
|
|
end,
|
|
})
|
|
|
|
minetest.register_tool("getitem:bag", {
|
|
description = S("Bag of Everything"),
|
|
_tt_help = S("Grants access to all items"),
|
|
inventory_image = "getitem_bag.png",
|
|
wield_image = "getitem_bag.png",
|
|
groups = { disable_repair = 1, not_in_creative_inventory = 1 },
|
|
on_use = function(itemstack, user)
|
|
if user and user:is_player() then
|
|
local name = user:get_player_name()
|
|
show_formspec(name)
|
|
end
|
|
end,
|
|
})
|
|
|
|
minetest.register_node("getitem:chest", {
|
|
description = S("Chest of Everything"),
|
|
_tt_help = S("Grants access to all items"),
|
|
tiles = {
|
|
"getitem_chest_top.png",
|
|
"getitem_chest_bottom.png",
|
|
"getitem_chest_side.png",
|
|
"getitem_chest_side.png",
|
|
"getitem_chest_side.png",
|
|
"getitem_chest_front.png",
|
|
},
|
|
paramtype2 = "facedir",
|
|
groups = { dig_immediate=2, not_in_creative_inventory = 1},
|
|
is_ground_content = false,
|
|
on_construct = function(pos)
|
|
local meta = minetest.get_meta(pos)
|
|
meta:set_string("infotext", S("Chest of Everything"))
|
|
end,
|
|
on_rightclick = function(pos, node, clicker)
|
|
if clicker and clicker:is_player() then
|
|
local name = clicker:get_player_name()
|
|
show_formspec(name)
|
|
end
|
|
end,
|
|
})
|
|
|
|
local getitem_table
|
|
|
|
minetest.register_on_mods_loaded(function()
|
|
local items = {}
|
|
for itemstring,_ in pairs(minetest.registered_items) do
|
|
if itemstring ~= "" and itemstring ~= "unknown" and itemstring ~= "ignore" then
|
|
table.insert(items, itemstring)
|
|
end
|
|
end
|
|
--[[ Sort items in this order:
|
|
* Nodes
|
|
* Tools
|
|
* Craftitems
|
|
* items from this mod (come last) ]]
|
|
local function compare(item1, item2)
|
|
local def1 = minetest.registered_items[item1]
|
|
local def2 = minetest.registered_items[item2]
|
|
local tool1 = def1.type == "tool"
|
|
local tool2 = def2.type == "tool"
|
|
local craftitem1 = def1.type == "craft"
|
|
local craftitem2 = def2.type == "craft"
|
|
local node1 = def1.type == "node"
|
|
local node2 = def2.type == "node"
|
|
local nici1 = minetest.get_item_group(item1, "not_in_creative_inventory") == 1 or not def1.description
|
|
local nici2 = minetest.get_item_group(item2, "not_in_creative_inventory") == 1 or not def2.description
|
|
local getitem1 = string.sub(item1, 1, 8) == "getitem:"
|
|
local getitem2 = string.sub(item2, 1, 8) == "getitem:"
|
|
if getitem1 and not getitem2 then
|
|
return false
|
|
elseif not getitem1 and getitem2 then
|
|
return true
|
|
elseif node1 and not node2 then
|
|
return true
|
|
elseif not node1 and node2 then
|
|
return false
|
|
elseif tool1 and not tool2 then
|
|
return true
|
|
elseif not tool1 and tool2 then
|
|
return false
|
|
elseif craftitem1 and not craftitem2 then
|
|
return true
|
|
elseif not craftitem1 and craftitem2 then
|
|
return false
|
|
else
|
|
return item1 < item2
|
|
end
|
|
end
|
|
table.sort(items, compare)
|
|
|
|
max_page = math.ceil(#items / SLOTS)
|
|
|
|
getitem_table = items
|
|
end)
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
add_detached_inventories(player)
|
|
local name = player:get_player_name()
|
|
local inv = detached_inventories[name].items
|
|
inv:set_size("main", #getitem_table)
|
|
inv:set_list("main", {})
|
|
for i=1, #getitem_table do
|
|
inv:add_item("main", getitem_table[i])
|
|
end
|
|
current_pages[name] = 1
|
|
end)
|
|
|
|
minetest.register_on_leaveplayer(function(player)
|
|
local name = player:get_player_name()
|
|
current_pages[name] = nil
|
|
end)
|