forked from MineClone5/MineClone5
Blast Protection; Fire Protection; Projectile Protection; Feather Falling; Thorns
This commit is contained in:
parent
b53ae0df19
commit
a3cf6b0e5d
|
@ -1,5 +1,13 @@
|
||||||
-- Taken from https://minecraft.gamepedia.com/Enchanting
|
-- Taken from https://minecraft.gamepedia.com/Enchanting
|
||||||
|
|
||||||
|
local function increase_damage(damage_group, factor)
|
||||||
|
return function(itemstack, level)
|
||||||
|
local tool_capabilities = itemstack:get_tool_capabilities()
|
||||||
|
tool_capabilities.damage_groups[damage_group] = (tool_capabilities.damage_groups[damage_group] or 0) + level * factor
|
||||||
|
itemstack:get_meta():set_tool_capabilities(tool_capabilities)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- requires engine change
|
-- requires engine change
|
||||||
--[[mcl_enchanting.enchantments.aqua_affinity = {
|
--[[mcl_enchanting.enchantments.aqua_affinity = {
|
||||||
name = "Aqua Affinity",
|
name = "Aqua Affinity",
|
||||||
|
@ -15,14 +23,6 @@
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}]]--
|
}]]--
|
||||||
|
|
||||||
local function increase_damage(damage_group, factor)
|
|
||||||
return function(itemstack, level)
|
|
||||||
local tool_capabilities = itemstack:get_tool_capabilities()
|
|
||||||
tool_capabilities.damage_groups[damage_group] = (tool_capabilities.damage_groups[damage_group] or 0) + level * factor
|
|
||||||
itemstack:get_meta():set_tool_capabilities(tool_capabilities)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented
|
-- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented
|
||||||
mcl_enchanting.enchantments.bane_of_arthropods = {
|
mcl_enchanting.enchantments.bane_of_arthropods = {
|
||||||
name = "Bane of Arthropods",
|
name = "Bane of Arthropods",
|
||||||
|
@ -38,7 +38,7 @@ mcl_enchanting.enchantments.bane_of_arthropods = {
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- unimplemented
|
-- implemented in mcl_armor
|
||||||
mcl_enchanting.enchantments.blast_protection = {
|
mcl_enchanting.enchantments.blast_protection = {
|
||||||
name = "Blast Protection",
|
name = "Blast Protection",
|
||||||
max_level = 4,
|
max_level = 4,
|
||||||
|
@ -123,7 +123,7 @@ mcl_enchanting.enchantments.efficiency = {
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- unimplemented
|
-- implemented in mcl_armor
|
||||||
mcl_enchanting.enchantments.feather_falling = {
|
mcl_enchanting.enchantments.feather_falling = {
|
||||||
name = "Feather Falling",
|
name = "Feather Falling",
|
||||||
max_level = 4,
|
max_level = 4,
|
||||||
|
@ -152,7 +152,7 @@ mcl_enchanting.enchantments.feather_falling = {
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}]]--
|
}]]--
|
||||||
|
|
||||||
-- unimplemented
|
-- implemented in mcl_armor
|
||||||
mcl_enchanting.enchantments.fire_protection = {
|
mcl_enchanting.enchantments.fire_protection = {
|
||||||
name = "Fire Protection",
|
name = "Fire Protection",
|
||||||
max_level = 4,
|
max_level = 4,
|
||||||
|
@ -350,7 +350,7 @@ mcl_enchanting.enchantments.power = {
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- unimplemented
|
-- implemented in mcl_armor
|
||||||
mcl_enchanting.enchantments.projectile_protection = {
|
mcl_enchanting.enchantments.projectile_protection = {
|
||||||
name = "Projectile Protection",
|
name = "Projectile Protection",
|
||||||
max_level = 4,
|
max_level = 4,
|
||||||
|
@ -485,7 +485,7 @@ mcl_enchanting.enchantments.soul_speed = {
|
||||||
requires_tool = false,
|
requires_tool = false,
|
||||||
}]]--
|
}]]--
|
||||||
|
|
||||||
-- unimplemented
|
-- implemented in mcl_armor
|
||||||
mcl_enchanting.enchantments.thorns = {
|
mcl_enchanting.enchantments.thorns = {
|
||||||
name = "Thorns",
|
name = "Thorns",
|
||||||
max_level = 3,
|
max_level = 3,
|
||||||
|
|
|
@ -284,8 +284,14 @@ local function trace_explode(pos, strength, raydirs, radius, drop_chance, fire,
|
||||||
impact = 0
|
impact = 0
|
||||||
end
|
end
|
||||||
local damage = math.floor((impact * impact + impact) * 7 * strength + 1)
|
local damage = math.floor((impact * impact + impact) * 7 * strength + 1)
|
||||||
if mod_death_messages and obj:is_player() then
|
if obj:is_player() then
|
||||||
mcl_death_messages.player_damage(obj, S("@1 was caught in an explosion.", obj:get_player_name()))
|
local name = obj:get_player_name()
|
||||||
|
if mod_death_messages then
|
||||||
|
mcl_death_messages.player_damage(obj, S("@1 was caught in an explosion.", name))
|
||||||
|
end
|
||||||
|
if rawget(_G, "armor") and armor.last_damage_types then
|
||||||
|
armor.last_damage_types[name] = "explosion"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local source = puncher
|
local source = puncher
|
||||||
if not source then
|
if not source then
|
||||||
|
|
|
@ -83,6 +83,9 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
|
||||||
|
|
||||||
-- Direct hit, no fire... just plenty of pain
|
-- Direct hit, no fire... just plenty of pain
|
||||||
hit_player = function(self, player)
|
hit_player = function(self, player)
|
||||||
|
if rawget(_G, "armor") and armor.last_damage_types then
|
||||||
|
armor.last_damage_types[player:get_player_name()] = "fireball"
|
||||||
|
end
|
||||||
player:punch(self.object, 1.0, {
|
player:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = {fleshy = 5},
|
damage_groups = {fleshy = 5},
|
||||||
|
|
|
@ -71,6 +71,9 @@ mobs:register_arrow("mobs_mc:fireball", {
|
||||||
velocity = 15,
|
velocity = 15,
|
||||||
|
|
||||||
hit_player = function(self, player)
|
hit_player = function(self, player)
|
||||||
|
if rawget(_G, "armor") and armor.last_damage_types then
|
||||||
|
armor.last_damage_types[player:get_player_name()] = "fireball"
|
||||||
|
end
|
||||||
player:punch(self.object, 1.0, {
|
player:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = {fleshy = 6},
|
damage_groups = {fleshy = 6},
|
||||||
|
|
|
@ -18,6 +18,7 @@ armor = {
|
||||||
.."listring[current_player;craft]",
|
.."listring[current_player;craft]",
|
||||||
textures = {},
|
textures = {},
|
||||||
default_skin = "character",
|
default_skin = "character",
|
||||||
|
last_damage_types = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
if minetest.get_modpath("mcl_skins") then
|
if minetest.get_modpath("mcl_skins") then
|
||||||
|
@ -497,13 +498,16 @@ end)
|
||||||
minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
||||||
local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]")
|
local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]")
|
||||||
if name and hp_change < 0 then
|
if name and hp_change < 0 then
|
||||||
|
local damage_type = armor.last_damage_types[name]
|
||||||
|
armor.last_damage_types[name] = nil
|
||||||
|
|
||||||
-- Armor doesn't protect from set_hp (commands like /kill),
|
-- Armor doesn't protect from set_hp (commands like /kill),
|
||||||
-- falling and drowning damage.
|
if reason.type == "set_hp" then
|
||||||
if reason.type == "set_hp" or reason.type == "drown" or reason.type == "fall" then
|
|
||||||
return hp_change
|
return hp_change
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall"
|
||||||
|
|
||||||
-- Account for potion effects (armor doesn't save the target)
|
-- Account for potion effects (armor doesn't save the target)
|
||||||
if reason.other == "poison" or reason.other == "harming" then
|
if reason.other == "poison" or reason.other == "harming" then
|
||||||
return hp_change
|
return hp_change
|
||||||
|
@ -515,18 +519,65 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
||||||
|
|
||||||
local total_points = 0
|
local total_points = 0
|
||||||
local total_toughness = 0
|
local total_toughness = 0
|
||||||
local protection_reduction = 0
|
local epf = 0
|
||||||
|
local thorns_damage = 0
|
||||||
|
local thorns_damage_regular = 0
|
||||||
for i=1, 6 do
|
for i=1, 6 do
|
||||||
local stack = player_inv:get_stack("armor", i)
|
local stack = player_inv:get_stack("armor", i)
|
||||||
if stack:get_count() > 0 then
|
if stack:get_count() > 0 then
|
||||||
|
local enchantments = mcl_enchanting.get_enchantments(stack)
|
||||||
|
local pts = stack:get_definition().groups["mcl_armor_points"] or 0
|
||||||
|
local tough = stack:get_definition().groups["mcl_armor_toughness"] or 0
|
||||||
|
total_points = total_points + pts
|
||||||
|
total_toughness = total_toughness + tough
|
||||||
|
|
||||||
|
local protection_level = enchantments.protection or 0
|
||||||
|
if protection_level > 0 then
|
||||||
|
epf = epf + protection_level * 1
|
||||||
|
end
|
||||||
|
local blast_protection_level = enchantments.blast_protection or 0
|
||||||
|
if blast_protection_level > 0 and damage_type == "explosion" then
|
||||||
|
epf = epf + blast_protection_level * 2
|
||||||
|
end
|
||||||
|
local fire_protection_level = enchantments.fire_protection or 0
|
||||||
|
if fire_protection_level > 0 and (damage_type == "fireball" or reason.type == "node_damage" and
|
||||||
|
(reason.node == "mcl_fire:fire" or reason.node == "mcl_core:lava_source" or reason.node == "mcl_core:lava_flowing")) then
|
||||||
|
epf = epf + fire_protection_level * 2
|
||||||
|
end
|
||||||
|
local projectile_protection_level = enchantments.projectile_protection or 0
|
||||||
|
if projectile_protection_level and (damage_type == "projectile" or damage_type == "fireball") then
|
||||||
|
epf = epf + projectile_protection_level * 2
|
||||||
|
end
|
||||||
|
local feather_falling_level = enchantments.feather_falling or 0
|
||||||
|
if feather_falling_level and reason.type == "fall" then
|
||||||
|
epf = epf + feather_falling_level * 3
|
||||||
|
end
|
||||||
|
|
||||||
|
local did_thorns_damage = false
|
||||||
|
local thorns_level = enchantments.thorns or 0
|
||||||
|
if thorns_level then
|
||||||
|
if thorns_level > 10 then
|
||||||
|
thorns_damage = thorns_damage + thorns_level - 10
|
||||||
|
did_thorns_damage = true
|
||||||
|
elseif thorns_damage_regular < 4 and thorns_level * 0.15 > math.random() then
|
||||||
|
local thorns_damage_regular_new = math.min(4, thorns_damage_regular + math.random(4))
|
||||||
|
thorns_damage = thorns_damage + thorns_damage_regular_new - thorns_damage_regular
|
||||||
|
thorns_damage_regular = thorns_damage_regular_new
|
||||||
|
did_thorns_damage = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Damage armor
|
-- Damage armor
|
||||||
local use = stack:get_definition().groups["mcl_armor_uses"] or 0
|
local use = stack:get_definition().groups["mcl_armor_uses"] or 0
|
||||||
local enchantments = mcl_enchanting.get_enchantments(stack)
|
if use > 0 and regular_reduction then
|
||||||
if enchantments.unbreaking then
|
local unbreaking_level = enchantments.unbreaking or 0
|
||||||
use = use / (0.6 + 0.4 / (enchantments.unbreaking + 1))
|
if unbreaking_level > 0 then
|
||||||
|
use = use / (0.6 + 0.4 / (unbreaking_level + 1))
|
||||||
end
|
end
|
||||||
if use > 0 then
|
|
||||||
local wear = armor_damage * math.floor(65536/use)
|
local wear = armor_damage * math.floor(65536/use)
|
||||||
|
if did_thorns_damage then
|
||||||
|
wear = wear * 3
|
||||||
|
end
|
||||||
stack:add_wear(wear)
|
stack:add_wear(wear)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -538,26 +589,34 @@ minetest.register_on_player_hpchange(function(player, hp_change, reason)
|
||||||
armor:set_player_armor(player)
|
armor:set_player_armor(player)
|
||||||
armor:update_inventory(player)
|
armor:update_inventory(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pts = stack:get_definition().groups["mcl_armor_points"] or 0
|
|
||||||
local tough = stack:get_definition().groups["mcl_armor_toughness"] or 0
|
|
||||||
total_points = total_points + pts
|
|
||||||
total_toughness = total_toughness + tough
|
|
||||||
if enchantments.protection then
|
|
||||||
protection_reduction = protection_reduction + enchantments.protection * 0.04
|
|
||||||
end
|
|
||||||
-- if enchantments.blast_protection and then
|
|
||||||
-- protection_reduction = protection_reduction + enchantments.blast_protection * 0.08
|
|
||||||
-- end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local damage = math.abs(hp_change)
|
local damage = math.abs(hp_change)
|
||||||
|
|
||||||
|
if regular_reduction then
|
||||||
-- Damage calculation formula (from <https://minecraft.gamepedia.com/Armor#Damage_protection>)
|
-- Damage calculation formula (from <https://minecraft.gamepedia.com/Armor#Damage_protection>)
|
||||||
damage = damage * (1 - math.min(20, math.max((total_points/5), total_points - damage / (2+(total_toughness/4)))) / 25)
|
damage = damage * (1 - math.min(20, math.max((total_points/5), total_points - damage / (2+(total_toughness/4)))) / 25)
|
||||||
damage = damage * (1 - math.min(1, protection_reduction))
|
end
|
||||||
|
damage = damage * (1 - (math.min(20, epf) / 25))
|
||||||
damage = math.floor(damage+0.5)
|
damage = math.floor(damage+0.5)
|
||||||
|
|
||||||
|
if reason.type == "punch" and thorns_damage > 0 then
|
||||||
|
local obj = reason.object
|
||||||
|
if obj then
|
||||||
|
local luaentity = obj:get_luaentity()
|
||||||
|
if luaentity then
|
||||||
|
local shooter = obj._shooter
|
||||||
|
if shooter then
|
||||||
|
obj = shooter
|
||||||
|
end
|
||||||
|
end
|
||||||
|
obj:punch(player, 1.0, {
|
||||||
|
full_punch_interval=1.0,
|
||||||
|
damage_groups = {fleshy = thorns_damage},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
hp_change = -math.abs(damage)
|
hp_change = -math.abs(damage)
|
||||||
|
|
||||||
armor.def[name].count = items
|
armor.def[name].count = items
|
||||||
|
|
|
@ -240,12 +240,14 @@ ARROW_ENTITY.on_step = function(self, dtime)
|
||||||
|
|
||||||
-- Punch target object but avoid hurting enderman.
|
-- Punch target object but avoid hurting enderman.
|
||||||
if not lua or lua.name ~= "mobs_mc:enderman" then
|
if not lua or lua.name ~= "mobs_mc:enderman" then
|
||||||
|
if obj:is_player() and rawget(_G, "armor") and armor.last_damage_types then
|
||||||
|
armor.last_damage_types[obj:get_player_name()] = "projectile"
|
||||||
|
end
|
||||||
damage_particles(self.object:get_pos(), self._is_critical)
|
damage_particles(self.object:get_pos(), self._is_critical)
|
||||||
self.object:set_pos(vector.subtract(obj:get_pos(), vector.multiply(vector.normalize(self.object:get_velocity()), 2)))
|
|
||||||
obj:punch(self.object, 1.0, {
|
obj:punch(self.object, 1.0, {
|
||||||
full_punch_interval=1.0,
|
full_punch_interval=1.0,
|
||||||
damage_groups={fleshy=self._damage},
|
damage_groups={fleshy=self._damage},
|
||||||
}, nil)
|
}, self.object:get_velocity())
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue