diff --git a/TODO.txt b/TODO.txt index 0f755ed..743eb23 100644 --- a/TODO.txt +++ b/TODO.txt @@ -4,5 +4,4 @@ TODO: - update inventories when items are replaced: - creative - storage (chests, etc.) -- update player inventories on login - fix top nodes disappearing with /replace_node command diff --git a/api.lua b/api.lua index 8911c86..3c1a17b 100644 --- a/api.lua +++ b/api.lua @@ -43,6 +43,82 @@ function cleaner.register_node_removal(src) }) end +local function update_list(inv, listname, src, tgt) + if not inv then + cleaner.log("error", "cannot update list of unknown inventory") + return + end + + local list = inv:get_list(listname) + if not list then + cleaner.log("warning", "unknown inventory list: " .. listname) + return + end + + for idx, stack in pairs(list) do + if stack:get_name() == src then + local new_stack = ItemStack(tgt) + new_stack:set_count(stack:get_count()) + inv:set_stack(listname, idx, new_stack) + end + end +end + +--- Replaces an item with another registered item. +-- +-- @tparam string src Technical name of item to be replaced. +-- @tparam string tgt Technical name of item to be used in place. +-- @tparam[opt] bool update_players `true` updates inventory lists associated with players (default: `false`). +function cleaner.replace_item(src, tgt, update_players) + update_players = not (update_players ~= true) + + if not core.registered_items[tgt] then + return false, S('Cannot use unknown item "@1" as replacement.', tgt) + end + + if not core.registered_items[src] then + cleaner.log("info", "\"" .. src .. "\" not registered, not unregistering") + else + cleaner.log("warning", "overriding registered item \"" .. src .. "\"") + + core.unregister_item(src) + if core.registered_items[src] then + cleaner.log("error", "could not unregister \"" .. src .. "\"") + end + end + + core.register_alias(src, tgt) + if core.registered_aliases[src] == tgt then + cleaner.log("info", "registered alias \"" .. src .. "\" for \"" .. tgt .. "\"") + else + cleaner.log("error", "could not register alias \"" .. src .. "\" for \"" .. tgt .. "\"") + end + + local bags = core.get_modpath("bags") ~= nil + local armor = core.get_modpath("3d_armor") ~= nil + + -- update player inventories + if update_players then + for _, player in ipairs(core.get_connected_players()) do + local pinv = player:get_inventory() + update_list(pinv, "main", src, tgt) + + if bags then + for i = 1, 4 do + update_list(pinv, "bag" .. i .. "contents", src, tgt) + end + end + + if armor then + local armor_inv = core.get_inventory({type="detached", name=player:get_player_name() .. "_armor"}) + update_list(armor_inv, "armor", src, tgt) + end + end + end + + return true +end + --- Registeres an item to be replaced. -- -- @tparam string src Technical name of item to be replaced. diff --git a/chat.lua b/chat.lua index b781250..0e4a4dc 100644 --- a/chat.lua +++ b/chat.lua @@ -180,61 +180,6 @@ core.register_chatcommand(cmd_repo.node.cmd_rem, { end, }) -local function update_list(inv, listname, src, tgt) - if not inv then - cleaner.log("error", "cannot update list of unknown inventory") - return - end - - local list = inv:get_list(listname) - if not list then - cleaner.log("warning", "unknown inventory list: " .. listname) - return - end - - for idx, stack in pairs(list) do - if stack:get_name() == src then - local new_stack = ItemStack(tgt) - new_stack:set_count(stack:get_count()) - inv:set_stack(listname, idx, new_stack) - end - end -end - -local function replace_item(src, tgt) - if not core.registered_items[tgt] then - return false, S('Cannot use unknown item "@1" as replacement.', tgt) - end - - if core.registered_items[src] then - core.unregister_item(src) - end - - core.register_alias(src, tgt) - - local bags = core.get_modpath("bags") ~= nil - local armor = core.get_modpath("3d_armor") ~= nil - - -- update player inventories - for _, player in ipairs(core.get_connected_players()) do - local pinv = player:get_inventory() - update_list(pinv, "main", src, tgt) - - if bags then - for i = 1, 4 do - update_list(pinv, "bag" .. i .. "contents", src, tgt) - end - end - - if armor then - local armor_inv = core.get_inventory({type="detached", name=player:get_player_name() .. "_armor"}) - update_list(armor_inv, "armor", src, tgt) - end - end - - return true -end - --- Replaces an item. -- -- @chatcmd replace_item @@ -255,7 +200,7 @@ core.register_chatcommand(cmd_repo.item.cmd, { local tgt = src[2] src = src[1] - local retval, msg = replace_item(src, tgt) + local retval, msg = cleaner.replace_item(src, tgt, true) if not retval then return false, msg end diff --git a/items.lua b/items.lua index 85015e6..02cde65 100644 --- a/items.lua +++ b/items.lua @@ -41,26 +41,9 @@ core.register_on_mods_loaded(function() for i_old, i_new in pairs(cleaner.get_replace_items()) do cleaner.log("action", "registering item \"" .. i_old .. "\" to be replaced with \"" .. i_new .. "\"") - if not core.registered_items[i_old] then - cleaner.log("info", "\"" .. i_old .. "\" not registered, not unregistering") - else - cleaner.log("warning", "overriding registered item \"" .. i_old .. "\"") - - core.unregister_item(i_old) - if core.registered_items[i_old] then - cleaner.log("error", "could not unregister \"" .. i_old .. "\"") - end - end - - if not core.registered_items[i_new] then - cleaner.log("warning", "adding alias for unregistered item \"" .. i_new .. "\"") - end - - core.register_alias(i_old, i_new) - if core.registered_aliases[i_old] == i_new then - cleaner.log("info", "registered alias \"" .. i_old .. "\" for \"" .. i_new .. "\"") - else - cleaner.log("error", "could not register alias \"" .. i_old .. "\" for \"" .. i_new .. "\"") + local retval, msg = cleaner.replace_item(i_old, i_new) + if not retval then + cleaner.log("warning", msg) end end end)