From 91a73dd440a9723e9b685de41239007dffcb65e6 Mon Sep 17 00:00:00 2001 From: mckaygerhard Date: Sun, 9 Jan 2022 00:53:19 -0500 Subject: [PATCH] API: complete Divide armor wear amongst number of pieces worn * Added now complete feature of Divide armor wear amongst number of pieces worn backported https://github.com/minetest-mods/3d_armor/commit/3ddcbae968c8ad8bf07762d86e6c46bc48fec795 * Added equip, unequip and get_weared_armor_elements functions backporting https://github.com/minetest-mods/3d_armor/commit/294338d3b09cd1509bb474e8feefac5288da4fe3 * Added remove_all function backported from https://github.com/minetest-mods/3d_armor/commit/e34635cb694cbcff4031281fb0e04a2675716340 * finally fix for issue #24 but backported for minetest 0.4 and 4.0 --- 3d_armor/README.txt | 12 ++++++++ 3d_armor/api.lua | 70 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/3d_armor/README.txt b/3d_armor/README.txt index 400d4945..4e86744e 100644 --- a/3d_armor/README.txt +++ b/3d_armor/README.txt @@ -163,6 +163,18 @@ Adds wear to a single armor itemstack, triggers `on_damage` callbacks and updates the necessary inventories. Also handles item destruction callbacks and so should NOT be called from `on_unequip` to avoid an infinite loop. +armor:remove_all(player) + +Removes all armors from the player's inventory without triggering any callback. + +armor:equip(player, armor_name) + +Equip the armor, removing the itemstack from the main inventory if there's one. + +armor:unequip(player, armor_name) + +Unequip the armor, adding the itemstack to the main inventory. + armor:update_skin(player_name) Triggers a skin update with the same action as if a field with `skins_set` was submitted. diff --git a/3d_armor/api.lua b/3d_armor/api.lua index c4c4325c..7c2d4baa 100644 --- a/3d_armor/api.lua +++ b/3d_armor/api.lua @@ -402,6 +402,12 @@ end armor.damage = function(self, player, index, stack, use) local old_stack = ItemStack(stack) + local worn_armor = armor:get_weared_armor_elements(player) + local armor_worn_cnt = 0 + for k,v in pairs(worn_armor) do + armor_worn_cnt = armor_worn_cnt + 1 + end + use = math.ceil(use/armor_worn_cnt) stack:add_wear(use) self:run_callbacks("on_damage", player, index, stack) self:set_inventory_stack(player, index, stack) @@ -412,6 +418,70 @@ armor.damage = function(self, player, index, stack, use) end end +armor.get_weared_armor_elements = function(self, player) + local name, inv = self:get_valid_player(player, "[get_weared_armor]") + local weared_armor = {} + if not name then + return + end + for i=1, inv:get_size("armor") do + local item_name = inv:get_stack("armor", i):get_name() + local element = self:get_element(item_name) + if element ~= nil then + weared_armor[element] = item_name + end + end + return weared_armor +end + +armor.equip = function(self, player, armor_name) + local name, inv = self:get_valid_player(player, "[equip]") + local weared_armor = self:get_weared_armor_elements(player) + local armor_element = self:get_element(armor_name) + if not name then + return + elseif self:get_element(armor_name) == nil then + return + elseif inv:contains_item("armor", ItemStack(armor_name)) then + return + end + if weared_armor[armor_element] ~= nil then + self:unequip(player, weared_armor[armor_element]) + end + inv:add_item("armor", ItemStack(armor_name)) + minetest.after(0, function() player:get_inventory():remove_item("main", ItemStack(armor_name)) end) + self:set_player_armor(player) + self:save_armor_inventory(player) +end + +armor.unequip = function(self, player, armor_name) + local name, inv = self:get_valid_player(player, "[unequip]") + if not name then + return + elseif self:get_element(armor_name) == nil then + return + elseif not inv:contains_item("armor", ItemStack(armor_name)) then + return + end + inv:remove_item("armor", ItemStack(armor_name)) + minetest.after(0, function() player:get_inventory():add_item("main", ItemStack(armor_name)) end) + self:set_player_armor(player) + self:save_armor_inventory(player) + self:save_armor_inventory(player) +end + +armor.remove_all = function(self, player) + local name, armor_inv = self:get_valid_player(player, "[remove_all]") + local name, inv = self:get_valid_player(player, "[remove_all]") + if not name then + return + end + armor_inv:set_list("armor", {}) + inv:set_list("armor", {}) + self:set_player_armor(player) + self:save_armor_inventory(player) +end + armor.get_player_skin = function(self, name) if (self.skin_mod == "skins" or self.skin_mod == "simple_skins") and skins.skins[name] then return skins.skins[name]..".png"