diff --git a/3d_armor/api.lua b/3d_armor/api.lua index a7890f5..1d56528 100644 --- a/3d_armor/api.lua +++ b/3d_armor/api.lua @@ -481,20 +481,42 @@ armor.save_armor_inventory = function(self, player) if not name then return end + local armor_list = {} + local armor_list_string = player:get_attribute("3d_armor_inventory") + if armor_list_string then + for i, item in pairs(minetest.deserialize(armor_list_string)) do + armor_list[item] = item ~= "" and i or nil + end + end + -- Workaround for detached inventory swap exploit local elements = {} local player_inv = player:get_inventory() for i = 1, 6 do local stack = inv:get_stack("armor", i) - local element = self:get_element(stack:get_name()) - if element and not elements[element] then - elements[element] = true; - else - inv:remove_item("armor", stack) - if player_inv and player_inv:room_for_item("main", stack) then - player_inv:add_item("main", stack) + if stack:get_count() > 0 then + local item = stack:get_name() + local element = self:get_element(item) + if element and not elements[element] then + if armor_list[item] then + armor_list[item] = nil + else + -- Item was not in previous inventory + armor:run_callbacks("on_equip", player, i, stack) + end + elements[element] = true; + else + inv:remove_item("armor", stack) + if player_inv and player_inv:room_for_item("main", stack) then + player_inv:add_item("main", stack) + end end end end + for item, i in pairs(armor_list) do + local stack = ItemStack(item) + -- Previous item is not in current inventory + armor:run_callbacks("on_unequip", player, i, stack) + end player:set_attribute("3d_armor_inventory", self:serialize_inventory_list(inv:get_list("armor"))) end diff --git a/3d_armor/init.lua b/3d_armor/init.lua index 34811a5..ad44359 100644 --- a/3d_armor/init.lua +++ b/3d_armor/init.lua @@ -118,12 +118,10 @@ local function init_player_armor(player) local armor_inv = minetest.create_detached_inventory(name.."_armor", { on_put = function(inv, listname, index, stack, player) armor:save_armor_inventory(player) - armor:run_callbacks("on_equip", player, index, stack) armor:set_player_armor(player) end, on_take = function(inv, listname, index, stack, player) armor:save_armor_inventory(player) - armor:run_callbacks("on_unequip", player, index, stack) armor:set_player_armor(player) end, on_move = function(inv, from_list, from_index, to_list, to_index, count, player) @@ -132,11 +130,9 @@ local function init_player_armor(player) end, allow_put = function(inv, listname, index, put_stack, player) local element = armor:get_element(put_stack:get_name()) - if not element then return 0 end - for i = 1, 6 do local stack = inv:get_stack("armor", i) local def = stack:get_definition() or {} @@ -167,7 +163,9 @@ local function init_player_armor(player) end for i=1, 6 do local stack = armor_inv:get_stack("armor", i) - armor:run_callbacks("on_equip", player, i, stack) + if stack:get_count() > 0 then + armor:run_callbacks("on_equip", player, i, stack) + end end armor.def[name] = { init_time = minetest.get_gametime(),