yl_speak_up/inventory.lua

127 lines
4.4 KiB
Lua

-- inventory management, trading and handling of quest items for talking to NPCs
-- cache the inventory of NPCs for easier access
yl_speak_up.npc_inventory = {}
-- where are they stored on the disk?
yl_speak_up.get_inventory_save_path = function(n_id)
return yl_speak_up.worldpath .. yl_speak_up.inventory_path .. DIR_DELIM .. "inv_" .. n_id .. ".json"
end
-- access the inventory of the NPC (only possible for players with the right priv)
yl_speak_up.get_fs_inventory = function(player, n_id, npc_name)
return "size[12,11]" ..
"label[2,-0.2;Inventory of "..minetest.formspec_escape(npc_name)..
" (ID: "..tostring(n_id).."):]"..
"list[detached:yl_npc_"..tostring(n_id)..";npc_main;0,0.3;12,6;]" ..
"list[current_player;main;2,6.85;8,1;]" ..
"list[current_player;main;2,8.08;8,3;8]" ..
"listring[detached:yl_npc_"..tostring(n_id)..";npc_main]" ..
"listring[current_player;main]" ..
"button[10.0,10.2;2,0.9;back_from_inventory;Back]"
end
-- save the inventory of the NPC with the id n_id
yl_speak_up.save_npc_inventory = function( n_id )
-- only save something if we actually can
if(not(n_id) or not(yl_speak_up.npc_inventory[ n_id ])) then
return
end
-- convert the inventory data to something we can actually store
local inv = yl_speak_up.npc_inventory[ n_id ]
local inv_as_table = {}
for i=1, inv:get_size("npc_main") do
local stack = inv:get_stack("npc_main", i)
-- only save those slots that are not empty
if(not(stack:is_empty())) then
inv_as_table[ i ] = stack:to_table()
end
end
-- convert the table into json
local json = minetest.write_json( inv_as_table )
-- get a file name for storing the data
local file_name = yl_speak_up.get_inventory_save_path(n_id)
-- actually store it on disk
minetest.safe_file_write(file_name, json)
end
-- create and load the detached inventory in yl_speak_up.after_activate;
-- direct access to this inventory is only possible for players with the right privs
yl_speak_up.load_npc_inventory = function(n_id)
if(not(n_id)) then
return
end
-- the inventory is already loaded
if( yl_speak_up.npc_inventory[ n_id ]) then
return
end
-- create the detached inventory (it is empty for now)
local npc_inv = minetest.create_detached_inventory("yl_npc_"..tostring(n_id), {
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
if(not(yl_speak_up.may_edit_npc(player, n_id))) then
return 0
end
return count
end,
-- Called when a player wants to move items inside the inventory.
-- Return value: number of items allowed to move.
allow_put = function(inv, listname, index, stack, player)
if(not(yl_speak_up.may_edit_npc(player, n_id))) then
return 0
end
return stack:get_count()
end,
-- Called when a player wants to put something into the inventory.
-- Return value: number of items allowed to put.
-- Return value -1: Allow and don't modify item count in inventory.
allow_take = function(inv, listname, index, stack, player)
if(not(yl_speak_up.may_edit_npc(player, n_id))) then
return 0
end
return stack:get_count()
end
-- Called when a player wants to take something out of the inventory.
-- Return value: number of items allowed to take.
-- Return value -1: Allow and don't modify item count in inventory.
-- on_move = function(inv, from_list, from_index, to_list, to_index, count, player) end,
-- on_put = function(inv, listname, index, stack, player) end,
-- on_take = function(inv, listname, index, stack, player) end,
-- Called after the actual action has happened, according to what was
-- allowed.
-- No return value.
})
-- the NPC needs enough room for trade items, payment and questitems
npc_inv:set_size("npc_main", 6*12)
-- cache a pointer to this inventory for easier access
yl_speak_up.npc_inventory[ n_id ] = npc_inv
-- find out where the inventory of the NPC is stored
local file_name = yl_speak_up.get_inventory_save_path(n_id)
-- load the data from the file
local file, err = io.open(file_name, "r")
if err then
return
end
io.input(file)
local text = io.read()
local inv_as_table = minetest.parse_json(text)
io.close(file)
if(type(inv_as_table) ~= "table") then
return
end
-- restore the inventory
for i=1, npc_inv:get_size("npc_main") do
npc_inv:set_stack("npc_main", i, ItemStack( inv_as_table[ i ]))
end
end