3d_armor - add nil check in armor.damage, partially fixes a bug
* add some check and backguard compatibility with older engines on each minetest loading time waith to 0.1 * backported "add nil check in `armor.damage`" from upstream https://github.com/minetest-mods/3d_armor/pull/109/files * by example shields already set the valid part to wear in6eb492b09c/shields/init.lua (L24)
with `armor.elements` but in 3darmor/init.lua there's no usage of the `armor.elements` table, just seems its taken from string configuration and convertered to table in line6eb492b09c/3d_armor/init.lua (L68)
using `armor.config.set_elements` event the `armor.elements` variable, its a miracle that the mod still works as spected! puff
This commit is contained in:
parent
6327ac1eb0
commit
5b37aa6387
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user