diff --git a/api.lua b/api.lua index bcc0848..f6afec5 100644 --- a/api.lua +++ b/api.lua @@ -303,6 +303,6 @@ end function unified_inventory.is_creative(playername) return minetest.check_player_privs(playername, {creative=true}) - or minetest.setting_getbool("creative_mode") + or minetest.settings:get_bool("creative_mode") end diff --git a/bags.lua b/bags.lua index a3e72ba..a946cb0 100644 --- a/bags.lua +++ b/bags.lua @@ -31,11 +31,18 @@ unified_inventory.register_button("bags", { hide_lite=true }) +local function get_player_bag_stack(player, i) + return minetest.get_inventory({ + type = "detached", + name = player:get_player_name() .. "_bags" + }):get_stack("bag" .. i, 1) +end + for i = 1, 4 do local bi = i unified_inventory.register_page("bag"..bi, { get_formspec = function(player) - local stack = player:get_inventory():get_stack("bag"..bi, 1) + local stack = get_player_bag_stack(player, bi) local image = stack:get_definition().inventory_image local formspec = ("image[7,0;1,1;"..image.."]" .."label[0,0;"..F(S("Bag @1", bi)).."]" @@ -58,7 +65,7 @@ for i = 1, 4 do end local inv = player:get_inventory() for i = 1, 4 do - local def = inv:get_stack("bag"..i, 1):get_definition() + local def = get_player_bag_stack(player, i):get_definition() local button if def.groups.bagslots then local list_name = "bag"..i.."contents" @@ -89,7 +96,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end for i = 1, 4 do if fields["bag"..i] then - local stack = player:get_inventory():get_stack("bag"..i, 1) + local stack = get_player_bag_stack(player, i) if not stack:get_definition().groups.bagslots then return end @@ -99,67 +106,117 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) end end) +local function save_bags_metadata(player, bags_inv) + local is_empty = true + local bags = {} + for i = 1, 4 do + local bag = "bag"..i + if not bags_inv:is_empty(bag) then + -- Stack limit is 1, otherwise use stack:to_string() + bags[i] = bags_inv:get_stack(bag, 1):get_name() + is_empty = false + end + end + if is_empty then + player:set_attribute("unified_inventory:bags", nil) + else + player:set_attribute("unified_inventory:bags", + minetest.serialize(bags)) + end +end + +local function load_bags_metadata(player, bags_inv) + local player_inv = player:get_inventory() + local bags_meta = player:get_attribute("unified_inventory:bags") + local bags = bags_meta and minetest.deserialize(bags_meta) or {} + local dirty_meta = false + if not bags_meta then + -- Backwards compatiblity + for i = 1, 4 do + local bag = "bag"..i + if not player_inv:is_empty(bag) then + -- Stack limit is 1, otherwise use stack:to_string() + bags[i] = player_inv:get_stack(bag, 1):get_name() + dirty_meta = true + end + end + end + -- Fill detached slots + for i = 1, 4 do + local bag = "bag"..i + bags_inv:set_size(bag, 1) + bags_inv:set_stack(bag, 1, bags[i] or "") + end + + if dirty_meta then + -- Requires detached inventory to be set up + save_bags_metadata(player, bags_inv) + end + + -- Clean up deprecated garbage after saving + for i = 1, 4 do + local bag = "bag"..i + player_inv:set_size(bag, 0) + end +end + minetest.register_on_joinplayer(function(player) local player_inv = player:get_inventory() local player_name = player:get_player_name() local bags_inv = minetest.create_detached_inventory(player_name.."_bags",{ on_put = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, stack) player:get_inventory():set_size(listname.."contents", stack:get_definition().groups.bagslots) - end, - on_take = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, nil) + save_bags_metadata(player, inv) end, allow_put = function(inv, listname, index, stack, player) local new_slots = stack:get_definition().groups.bagslots - if new_slots then - local player_inv = player:get_inventory() - local old_slots = player_inv:get_size(listname.."contents") + if not new_slots then + return 0 + end + local player_inv = player:get_inventory() + local old_slots = player_inv:get_size(listname.."contents") - if new_slots >= old_slots then - return 1 - else - -- using a smaller bag, make sure it fits - local old_list = player_inv:get_list(listname.."contents") - local new_list = {} - local slots_used = 0 - local use_new_list = false + if new_slots >= old_slots then + return 1 + end - for i, v in ipairs(old_list) do - if v and not v:is_empty() then - slots_used = slots_used + 1 - use_new_list = i > new_slots - new_list[slots_used] = v - end - end - if new_slots >= slots_used then - if use_new_list then - player_inv:set_list(listname.."contents", new_list) - end - return 1 - end + -- using a smaller bag, make sure it fits + local old_list = player_inv:get_list(listname.."contents") + local new_list = {} + local slots_used = 0 + local use_new_list = false + + for i, v in ipairs(old_list) do + if v and not v:is_empty() then + slots_used = slots_used + 1 + use_new_list = i > new_slots + new_list[slots_used] = v end end - return 0 + if new_slots >= slots_used then + if use_new_list then + player_inv:set_list(listname.."contents", new_list) + end + return 1 + end end, allow_take = function(inv, listname, index, stack, player) if player:get_inventory():is_empty(listname.."contents") then return stack:get_count() - else - return 0 end + return 0 end, - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) + on_take = function(inv, listname, index, stack, player) + player:get_inventory():set_size(listname.."contents", 0) + save_bags_metadata(player, inv) + end, + allow_move = function() return 0 end, }, player_name) - for i=1,4 do - local bag = "bag"..i - player_inv:set_size(bag, 1) - bags_inv:set_size(bag, 1) - bags_inv:set_stack(bag, 1, player_inv:get_stack(bag, 1)) - end + + load_bags_metadata(player, bags_inv) end) -- register bag tools diff --git a/init.lua b/init.lua index 330bdff..1c73fad 100644 --- a/init.lua +++ b/init.lua @@ -1,4 +1,4 @@ --- Unified Inventory for Minetest 0.4.8+ +-- Unified Inventory for Minetest >= 0.4.16 local modpath = minetest.get_modpath(minetest.get_current_modname()) local worldpath = minetest.get_worldpath() @@ -37,10 +37,10 @@ unified_inventory = { gettext = S, -- "Lite" mode - lite_mode = minetest.setting_getbool("unified_inventory_lite"), + lite_mode = minetest.settings:get_bool("unified_inventory_lite"), -- Trash enabled - trash_enabled = (minetest.setting_getbool("unified_inventory_trash") ~= false), + trash_enabled = (minetest.settings:get_bool("unified_inventory_trash") ~= false), pagecols = 8, pagerows = 10, @@ -73,7 +73,7 @@ dofile(modpath.."/internal.lua") dofile(modpath.."/callbacks.lua") dofile(modpath.."/register.lua") -if minetest.setting_getbool("unified_inventory_bags") ~= false then +if minetest.settings:get_bool("unified_inventory_bags") ~= false then dofile(modpath.."/bags.lua") end diff --git a/register.lua b/register.lua index 27c8259..dd2b3cc 100644 --- a/register.lua +++ b/register.lua @@ -290,6 +290,8 @@ unified_inventory.register_page("craftguide", { alternates = #crafts craft = crafts[alternate] end + local has_creative = player_privs.give or player_privs.creative or + minetest.settings:get_bool("creative_mode") formspec = formspec.."background[0.5,"..(formspecy + 0.2)..";8,3;ui_craftguide_form.png]" formspec = formspec.."textarea["..craftresultx..","..craftresulty @@ -305,7 +307,7 @@ unified_inventory.register_page("craftguide", { formspec = formspec.."image["..no_pos..","..formspecy..";1.1,1.1;ui_no.png]" formspec = formspec..stack_image_button(item_pos, formspecy, 1.1, 1.1, "item_button_" ..other_dir[dir].."_", ItemStack(item_name)) - if player_privs.give == true or player_privs.creative == true or minetest.setting_getbool("creative_mode") == true then + if has_creative then formspec = formspec.."label[0,"..(formspecy + 2.10)..";" .. F(S("Give me:")) .. "]" .."button[0, "..(formspecy + 2.7)..";0.6,0.5;craftguide_giveme_1;1]" .."button[0.6,"..(formspecy + 2.7)..";0.7,0.5;craftguide_giveme_10;10]" @@ -382,7 +384,7 @@ unified_inventory.register_page("craftguide", { .."button[0.6,"..(formspecy + 1.5)..";0.7,0.5;craftguide_craft_10;10]" .."button[1.3,"..(formspecy + 1.5)..";0.8,0.5;craftguide_craft_max;" .. F(S("All")) .. "]" end - if player_privs.give == true or player_privs.creative == true or minetest.setting_getbool("creative_mode") == true then + if has_creative then formspec = formspec.."label[0,"..(formspecy + 2.1)..";" .. F(S("Give me:")) .. "]" .."button[0, "..(formspecy + 2.7)..";0.6,0.5;craftguide_giveme_1;1]" .."button[0.6,"..(formspecy + 2.7)..";0.7,0.5;craftguide_giveme_10;10]"