diff --git a/mods/3d_armor/3d_armor/api.lua b/mods/3d_armor/3d_armor/api.lua index acb29f2..e807dc6 100644 --- a/mods/3d_armor/3d_armor/api.lua +++ b/mods/3d_armor/3d_armor/api.lua @@ -414,15 +414,16 @@ armor.set_player_armor = function(self, player) end local state = 0 local count = 0 - local material = {count=1} local preview = armor:get_preview(name) local texture = "3d_armor_trans.png" - local textures = {} local physics = {} local attributes = {} local levels = {} local groups = {} local change = {} + local set_worn = {} + local armor_multi = 0 + local worn_armor = armor:get_weared_armor_elements(player) for _, phys in pairs(self.physics) do physics[phys] = 1 end @@ -478,21 +479,38 @@ armor.set_player_armor = function(self, player) local value = def.groups["armor_"..attr] or 0 attributes[attr] = attributes[attr] + value end - local mat = string.match(item, "%:.+_(.+)$") - if material.name then - if material.name == mat then - material.count = material.count + 1 + end + end + -- The following code compares player worn armor items against requirements + -- of which armor pieces are needed to be worn to meet set bonus requirements + for loc,item in pairs(worn_armor) do + local item_mat = string.match(item, "%:.+_(.+)$") + local worn_key = item_mat or "unknown" + + -- Perform location checks to ensure the armor is worn correctly + for k,set_loc in pairs(armor.config.set_elements)do + if set_loc == loc then + if set_worn[worn_key] == nil then + set_worn[worn_key] = 0 + set_worn[worn_key] = set_worn[worn_key] + 1 + else + set_worn[worn_key] = set_worn[worn_key] + 1 end - else - material.name = mat end end end + + -- Apply the armor multiplier only if the player is wearing a full set of armor + for mat_name,arm_piece_num in pairs(set_worn) do + if arm_piece_num == #armor.config.set_elements then + armor_multi = armor.config.set_multiplier + end + end for group, level in pairs(levels) do if level > 0 then level = level * armor.config.level_multiplier - if material.name and material.count == #self.elements then - level = level * 1.1 + if armor_multi ~= 0 then + level = level * armor.config.set_multiplier end end local base = self.registered_groups[group] @@ -661,6 +679,7 @@ end armor.damage = function(self, player, index, stack, use) local old_stack = ItemStack(stack) local worn_armor = armor:get_weared_armor_elements(player) + if not worn_armor then return end local armor_worn_cnt = 0 for k,v in pairs(worn_armor) do armor_worn_cnt = armor_worn_cnt + 1 @@ -701,8 +720,8 @@ end -- -- @function armor:equip -- @tparam ObjectRef player Player to whom item is equipped. --- @tparam armor_name itemstack Armor item to be equipped. --- @treturn armor_name Leftover item stack. +-- @tparam ItemStack itemstack Armor item to be equipped. +-- @treturn ItemStack Leftover item stack. armor.equip = function(self, player, itemstack) local name, armor_inv = self:get_valid_player(player, "[equip]") local armor_element = self:get_element(itemstack:get_name()) @@ -737,8 +756,8 @@ end -- -- @function armor:unequip -- @tparam ObjectRef player Player from whom item is removed. --- @tparam string armor_name Armor type identifier associated with the item --- to be removed (armor_name). +-- @tparam string armor_element Armor type identifier associated with the item +-- to be removed ("head", "torso", "hands", "shield", "legs", "feet", etc.). armor.unequip = function(self, player, armor_element) local name, armor_inv = self:get_valid_player(player, "[unequip]") if not name then @@ -805,7 +824,7 @@ end -- @function armor:update_skin -- @tparam string name Player name. armor.update_skin = function(self, name) - minetest.after(0, function() + minetest.after(0.1, function() local pplayer = minetest.get_player_by_name(name) if pplayer then self.textures[name].skin = self:get_player_skin(name) @@ -926,7 +945,7 @@ armor.load_armor_inventory = function(self, player) end end ---- Saves armor inventory in player attribute string "3d\_armor\_inventory". +--- Saves armor inventory in player attribute or `PlayerMetaRef` string "3d\_armor\_inventory". -- -- @function armor:save_armor_inventory -- @tparam ObjectRef player diff --git a/mods/3d_armor/3d_armor/init.lua b/mods/3d_armor/3d_armor/init.lua index 2ab6c09..31c6737 100644 --- a/mods/3d_armor/3d_armor/init.lua +++ b/mods/3d_armor/3d_armor/init.lua @@ -58,6 +58,10 @@ for material, _ in pairs(armor.materials) do end end +-- Convert set_elements to a Lua table splitting on blank spaces +local t_set_elements = armor.config.set_elements +armor.config.set_elements = string.split(t_set_elements, " ") + -- Remove torch damage if fire_protect_torch == false if armor.config.fire_protect_torch == false and armor.config.fire_protect == true then for k,v in pairs(armor.fire_nodes) do @@ -339,7 +343,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) local player_name = player:get_player_name() for field, _ in pairs(fields) do if string.find(field, "skins_set") then - minetest.after(0, function(player) + minetest.after(0.1, function(player) local skin = armor:get_player_skin(name) armor.textures[name].skin = skin armor:set_player_armor(player) @@ -351,7 +355,7 @@ end) minetest.register_on_joinplayer(function(player) armor.player_set_model(player, modelchar) local player_name = player:get_player_name() - minetest.after(0, function(player) + minetest.after(0.1, function(player) local pplayer = minetest.get_player_by_name(player_name) if pplayer and init_player_armor(player) == false then pending_players[player] = 0 @@ -476,26 +480,38 @@ minetest.register_globalstep(function(dtime) end end - if timer > armor.config.init_delay then - for player, count in pairs(pending_players) do - local remove = init_player_armor(player) == true - pending_players[player] = count + 1 - if remove == false and count > armor.config.init_times then - minetest.log("warning", "3d_armor: Failed to initialize player") - remove = true - end - if remove == true then - pending_players[player] = nil + if timer <= armor.config.init_delay then + return + end + timer = 0 + + for player, count in pairs(pending_players) do + local remove = init_player_armor(player) == true + pending_players[player] = count + 1 + if remove == false and count > armor.config.init_times then + minetest.log("warning", "3d_armor: Failed to initialize player") + remove = true + end + if remove == true then + pending_players[player] = nil + end + end + + -- water breathing protection, added by TenPlus1 + if armor.config.water_protect == true then + for _,player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + if armor.def[name].water > 0 and + player:get_breath() < 10 then + player:set_breath(10) end end - timer = 0 end end) --- Fire Protection and water breating, added by TenPlus1 - +-- Fire Protection, added by TenPlus1. if armor.config.fire_protect == true then - -- override hot nodes so they do not hurt player anywhere but mod + -- override any hot nodes that do not already deal damage for _, row in pairs(armor.fire_nodes) do if minetest.registered_nodes[row[1]] then minetest.override_item(row[1], {damage_per_second = 0}) @@ -534,9 +550,9 @@ if armor.config.water_protect == true or armor.config.fire_protect == true then -- fire protection if armor.config.fire_protect == true then local fire_damage = true - pos.y = pos.y + 1.4 -- head level + pos.y = pos.y + 1.41 -- head level local node_head = minetest.get_node(pos).name - pos.y = pos.y - 1.2 -- feet level + pos.y = pos.y - 1.21 -- feet level local node_feet = minetest.get_node(pos).name -- is player inside a hot node? for _, row in pairs(armor.fire_nodes) do