diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 1ffc87b34..5b94373d9 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -1,5 +1,8 @@ local S = minetest.get_translator("mcl_falling_nodes") local dmes = minetest.get_modpath("mcl_death_messages") ~= nil +local has_mcl_armor = minetest.get_modpath("mcl_armor") + +local his_creative_enabled = minetest.is_creative_enabled local get_falling_depth = function(self) if not self._startpos then @@ -13,9 +16,8 @@ local deal_falling_damage = function(self, dtime) if minetest.get_item_group(self.node.name, "falling_node_damage") == 0 then return end - -- Cause damage to any player it hits. + -- Cause damage to any entity it hits. -- Algorithm based on MC anvils. - -- TODO: Support smashing other objects, too. local pos = self.object:get_pos() if not self._startpos then -- Fallback @@ -23,30 +25,39 @@ local deal_falling_damage = function(self, dtime) end local objs = minetest.get_objects_inside_radius(pos, 1) for _,v in ipairs(objs) do - local hp = v:get_hp() - if v:is_player() and hp ~= 0 then - if not self._hit_players then - self._hit_players = {} - end + if v:is_player() then + local hp = v:get_hp() local name = v:get_player_name() - local hit = false - for _,v in ipairs(self._hit_players) do - if name == v then - hit = true + if hp ~= 0 then + if not self._hit_players then + self._hit_players = {} end - end - if not hit then - table.insert(self._hit_players, name) - local way = self._startpos.y - pos.y - local damage = (way - 1) * 2 - damage = math.min(40, math.max(0, damage)) - if damage >= 1 then - hp = hp - damage - if hp < 0 then - hp = 0 + local hit = false + for _,v in ipairs(self._hit_players) do + if name == v then + hit = true end - if v:is_player() then - -- TODO: Reduce damage if wearing a helmet + end + if not hit then + table.insert(self._hit_players, name) + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + hp = hp - damage + if hp < 0 then + hp = 0 + end + -- Reduce damage if wearing a helmet + local inv = v:get_inventory() + local helmet = inv:get_stack("armor", 2) + if has_mcl_armor and not helmet:is_empty() then + hp = hp/4*3 + if not his_creative_enabled(name) then + helmet:add_wear(65535/helmet:get_definition().groups.mcl_armor_uses) --TODO: be sure damage is exactly like mc (informations are missing in the mc wiki) + inv:set_stack("armor", 2, helmet) + end + end local msg if minetest.get_item_group(self.node.name, "anvil") ~= 0 then msg = S("@1 was smashed by a falling anvil.", v:get_player_name()) @@ -56,8 +67,35 @@ local deal_falling_damage = function(self, dtime) if dmes then mcl_death_messages.player_damage(v, msg) end + v:set_hp(hp, { type = "punch", from = "mod" }) + end + end + end + else + local hp = v:get_luaentity().health + if hp and hp ~= 0 then + if not self._hit_mobs then + self._hit_mobs = {} + end + local hit = false + for _,mob in ipairs(self._hit_mobs) do + if v == mob then + hit = true + end + end + --TODO: reduce damage for mobs then they will be able to wear armor + if not hit then + table.insert(self._hit_mobs, v) + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + hp = hp - damage + if hp < 0 then + hp = 0 + end + v:get_luaentity().health = hp end - v:set_hp(hp, { type = "punch", from = "mod" }) end end end