forked from VoxeLibre/VoxeLibre
Rework armor (WIP)
This commit is contained in:
parent
99357d467c
commit
9ce59d4438
|
@ -1,118 +0,0 @@
|
|||
local old_damage_handler = MCLObject.handle_damage
|
||||
|
||||
function MCLObject:handle_damage(hp, source)
|
||||
local hp_old = old_damage_handler(hp, source)
|
||||
if hp_old then
|
||||
return hp_old
|
||||
end
|
||||
|
||||
if source.bypasses_armor and source.bypasses_magic then
|
||||
return
|
||||
end
|
||||
|
||||
local heal_max = 0
|
||||
local items = 0
|
||||
local armor_damage = math.max(1, math.floor(math.abs(hp) / 4))
|
||||
|
||||
local total_points = 0
|
||||
local total_toughness = 0
|
||||
local epf = 0
|
||||
local thorns_damage = 0
|
||||
local thorns_damage_regular = 0
|
||||
|
||||
for location, stack in pairs(self:equipment():get_armor()) do
|
||||
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 == "burning" or 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
|
||||
local use = stack:get_definition().groups["mcl_armor_uses"] or 0
|
||||
if use > 0 and regular_reduction then
|
||||
local unbreaking_level = enchantments.unbreaking or 0
|
||||
if unbreaking_level > 0 then
|
||||
use = use / (0.6 + 0.4 / (unbreaking_level + 1))
|
||||
end
|
||||
local wear = armor_damage * math.floor(65536/use)
|
||||
if did_thorns_damage then
|
||||
wear = wear * 3
|
||||
end
|
||||
stack:add_wear(wear)
|
||||
end
|
||||
|
||||
local item = stack:get_name()
|
||||
armor_inv:set_stack("armor", i, stack)
|
||||
player_inv:set_stack("armor", i, stack)
|
||||
items = items + 1
|
||||
if stack:get_count() == 0 then
|
||||
armor:set_player_armor(player)
|
||||
armor:update_inventory(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
local damage = math.abs(hp_change)
|
||||
|
||||
if regular_reduction then
|
||||
-- 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)
|
||||
end
|
||||
damage = damage * (1 - (math.min(20, epf) / 25))
|
||||
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)
|
||||
return hp
|
||||
end
|
|
@ -1,18 +1,17 @@
|
|||
MCLDamageSource = class()
|
||||
|
||||
function MCLDamageSource:constructor(tbl, hitter)
|
||||
function MCLDamageSource:constructor(tbl)
|
||||
for k, v in pairs(tbl or {}) do
|
||||
self[k] = v
|
||||
end
|
||||
self.hitter = hitter
|
||||
end
|
||||
|
||||
MCLDamageSource:__getter("direct_object", function(self)
|
||||
local hitter = self.hitter
|
||||
if not hitter then
|
||||
local obj = self.raw_source_object
|
||||
if not obj then
|
||||
return
|
||||
end
|
||||
return mcl_object_mgr.get(hitter)
|
||||
return mcl_object_mgr.get(obj)
|
||||
end)
|
||||
|
||||
MCLDamageSource:__getter("source_object", function(self)
|
||||
|
|
|
@ -42,21 +42,3 @@ function MCLEntity:get_staticdata()
|
|||
|
||||
return minetest.serialize(data)
|
||||
end
|
||||
|
||||
function MCLEntity:calculate_knockback(...)
|
||||
return minetest.calculate_knockback(self.object, ...)
|
||||
end
|
||||
|
||||
function MCLEntity:on_punch(...)
|
||||
hp = MCLObject.on_punch(self, ...)
|
||||
|
||||
self.damage_info.info.knockback = self:calculate_knockback(...)
|
||||
end
|
||||
|
||||
function MCLEntity:on_damage(hp_change, source, info)
|
||||
MCLObject.on_damage(self, hp_change, source, info)
|
||||
|
||||
if info.knockback then
|
||||
self:add_velocity(info.knockback)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -69,7 +69,7 @@ function MCLEquipment:__armor(idx, name)
|
|||
end)
|
||||
end
|
||||
|
||||
local armor_slots = {"head", "chest", "legs", "feet"}
|
||||
local armor_slots = {"helmet", "chestplace", "leggings", "boots"}
|
||||
|
||||
for i, name in ipairs(armor_slots) do
|
||||
MCLEquipment:__armor(idx, name)
|
||||
|
|
|
@ -15,17 +15,29 @@ end
|
|||
MCLItemStack:__comparator("meta", mcl_types.match_meta)
|
||||
|
||||
function MCLItemStack:get_enchantment(name)
|
||||
return self:enchantments()[name]
|
||||
return self:enchantments()[name] or 0
|
||||
end
|
||||
|
||||
function MCLItemStack:has_enchantment(name)
|
||||
return self:get_enchantment(name) > 0
|
||||
end
|
||||
|
||||
function MCLItemStack:total_durability()
|
||||
end
|
||||
|
||||
function MCLItemStack:durability()
|
||||
local def = self.stack:get_definition()
|
||||
if def then
|
||||
local base_uses = def._mcl_uses
|
||||
local base_uses = def._durability
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function MCLItemStack:use_durability()
|
||||
end
|
||||
|
||||
function MCLItemStack:restore_durability()
|
||||
end
|
||||
|
||||
function MCLItemStack:get_group()
|
||||
end
|
||||
|
|
|
@ -8,11 +8,11 @@ function MCLMob:set_hp()
|
|||
self:meta():set_float("hp", hp)
|
||||
end
|
||||
|
||||
function MCLMob:on_damage(hp_change, source, info)
|
||||
MCLEntity.on_damage(self, hp_change, source, info)
|
||||
function MCLMob:on_damage(damage, source)
|
||||
MCLEntity.on_damage(self, damage, source)
|
||||
|
||||
local new_hp = self:get_hp()
|
||||
if new_hp <= 0 and new_hp + hp_change > 0 then
|
||||
if new_hp <= 0 and new_hp + damage > 0 then
|
||||
self:on_death(source)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -5,33 +5,32 @@ function MCLObject:constructor(obj)
|
|||
self.IS_MCL_OBJECT = true
|
||||
end
|
||||
|
||||
function MCLObject:on_punch(hitter, time_from_last_punch, tool_capabilities, dir, hp)
|
||||
local source = MCLDamageSource():punch(nil, hitter)
|
||||
function MCLObject:on_punch(hitter, time_from_last_punch, tool_capabilities, dir, damage)
|
||||
local source = MCLDamageSource({is_punch = true, raw_source_object = hitter})
|
||||
|
||||
hp = self:damage_modifier(hp, source) or hp
|
||||
damage = self:damage_modifier(damage, source) or damage
|
||||
|
||||
self.damage_info = {
|
||||
hp = hp,
|
||||
damage = damage,
|
||||
source = source,
|
||||
info = {
|
||||
tool_capabilities = tool_capabilities,
|
||||
},
|
||||
knockback = self:get_knockback(source, time_from_last_punch, tool_capabilities, dir, nil, damage),
|
||||
}
|
||||
|
||||
return hp
|
||||
return damage
|
||||
end
|
||||
|
||||
-- use this function to deal regular damage to an object (do NOT use :punch() unless toolcaps need to be handled)
|
||||
function MCLObject:damage(hp, source)
|
||||
hp = self:damage_modifier(hp, source) or hp
|
||||
self:set_hp(self:get_hp() - hp)
|
||||
function MCLObject:damage(damage, source, knockback)
|
||||
damage = self:damage_modifier(damage, source) or damage
|
||||
self:set_hp(self:get_hp() - damage)
|
||||
|
||||
self.damage_info = {
|
||||
hp = hp,
|
||||
damage = damage,
|
||||
source = source,
|
||||
knockback = knockback,
|
||||
}
|
||||
|
||||
return hp
|
||||
return damage
|
||||
end
|
||||
|
||||
function MCLObject:wield_index()
|
||||
|
@ -49,10 +48,6 @@ function MCLObject:set_hp(hp)
|
|||
self.object:set_hp(hp)
|
||||
end
|
||||
|
||||
function MCLObject:add_velocity(vel)
|
||||
self.object:add_velocity(vel)
|
||||
end
|
||||
|
||||
function MCLObject:death_drop(inventory, listname, index, stack)
|
||||
minetest.add_item(self.object:get_pos(), stack)
|
||||
inventory:set_stack(listname, index, nil)
|
||||
|
@ -71,19 +66,39 @@ function MCLObject:on_death(source)
|
|||
end
|
||||
end
|
||||
|
||||
function MCLObject:damage_modifier(hp, source)
|
||||
function MCLObject:damage_modifier(damage, source)
|
||||
if self.invulnerable and not source.bypasses_invulnerability then
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function MCLObject:on_damage(hp_change, source, info)
|
||||
function MCLObject:on_damage(damage, source, knockback)
|
||||
end
|
||||
|
||||
function MCLObject:get_knockback(source, time_from_last_punch, tool_capabilities, dir, distance, damage)
|
||||
local direct_object = source:direct_object()
|
||||
|
||||
return self:calculate_knockback(
|
||||
self.object,
|
||||
direct_object,
|
||||
time_from_last_punch or 1.0,
|
||||
tool_capabilities or {fleshy = damage},
|
||||
dir or vector.direction(direct_object:get_pos(), self.object:get_pos()),
|
||||
distance or vector.distance(direct_object:get_pos(), self.object:get_pos()),
|
||||
damage = damage,
|
||||
)
|
||||
end
|
||||
|
||||
MCLObject.calculate_knockback = minetest.calculate_knockback
|
||||
|
||||
function MCLObject:on_step()
|
||||
local damage_info = self.damage_info
|
||||
if damage_info then
|
||||
self.damage_info = nil
|
||||
self:on_damage(damage_info.hp, damage_info.source, damage_info.info)
|
||||
self:on_damage(damage_info.damage, damage_info.source)
|
||||
|
||||
if damage_info.knockback then
|
||||
self.object:add_velocity(damage_info.knockback)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,3 +13,13 @@ MCLPlayer:__override_pipe("death_drop", function(self, inventory, listname, inde
|
|||
return self, inventory, listname, index, stack
|
||||
end
|
||||
end)
|
||||
|
||||
function MCLPlayer:get_knockback(source, ...)
|
||||
if not source.is_punch then
|
||||
return MCLObject.get_knockback(self, source, ...)
|
||||
end
|
||||
end
|
||||
|
||||
function MCLPlayer:on_damage(damage, source, knockback)
|
||||
MCLObject.on_damage(self, damage, source, knockback)
|
||||
end
|
||||
|
|
|
@ -9,7 +9,6 @@ local modpath = minetest.get_modpath(minetest.get_current_modname())
|
|||
armor = {
|
||||
timer = 0,
|
||||
elements = {"head", "torso", "legs", "feet"},
|
||||
physics = {"jump","speed","gravity"},
|
||||
formspec = "size[8,8.5]image[2,0.75;2,4;armor_preview]"
|
||||
.."list[current_player;main;0,4.5;8,4;]"
|
||||
.."list[current_player;craft;4,1;3,3;]"
|
||||
|
@ -18,7 +17,6 @@ armor = {
|
|||
.."listring[current_player;craft]",
|
||||
textures = {},
|
||||
default_skin = "character",
|
||||
last_damage_types = {},
|
||||
}
|
||||
|
||||
if minetest.get_modpath("mcl_skins") then
|
||||
|
@ -33,7 +31,7 @@ elseif minetest.get_modpath("wardrobe") then
|
|||
skin_mod = "wardrobe"
|
||||
end
|
||||
|
||||
function armor.on_armor_use(itemstack, user, pointed_thing)
|
||||
function mcl_armor.rightclick_equip(itemstack, user, pointed_thing)
|
||||
if not user or user:is_player() == false then
|
||||
return itemstack
|
||||
end
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
local old_damage_modifier = MCLObject.damage_modifier
|
||||
|
||||
function MCLObject:damage_modifier(damage, source)
|
||||
local damage_old = old_damage_modifier(damage, source)
|
||||
if damage_old then
|
||||
return damage_old
|
||||
end
|
||||
|
||||
if damage < 0 then
|
||||
return
|
||||
end
|
||||
|
||||
if source.bypasses_armor and source.bypasses_magic then
|
||||
return
|
||||
end
|
||||
|
||||
local uses = math.max(1, math.floor(math.abs(damage) / 4))
|
||||
|
||||
local source_object = source:source_object()
|
||||
local equipment = self:equipment()
|
||||
|
||||
local points = self:base_armor_points()
|
||||
local toughness = 0
|
||||
local protection_factor = 0
|
||||
local thorns_damage_regular = 0
|
||||
local thorns_damage_irregular = 0
|
||||
local thorns_pieces = {}
|
||||
|
||||
for location, rawstack in pairs(equipment:get_armor()) do
|
||||
local stack = MCLItemStack(rawstack)
|
||||
|
||||
if not source.bypasses_armor then
|
||||
points = points + stack:group("armor_points")
|
||||
toughness = toughness + stack:group("armor_toughness")
|
||||
|
||||
stack:use_durability(uses)
|
||||
equipment[location](equipment, rawstack)
|
||||
end
|
||||
|
||||
if not source.bypasses_magic then
|
||||
protection_factor = protection_factor + 1 * stack:get_enchantment("protection")
|
||||
|
||||
if source.is_explosion then
|
||||
protection_factor = protection_factor + 2 * stack:get_enchantment("blast_protection")
|
||||
end
|
||||
|
||||
if source.is_fire then
|
||||
protection_factor = protection_factor + 2 * stack:get_enchantment("fire_protection")
|
||||
end
|
||||
|
||||
if source.is_projectile then
|
||||
protection_factor = protection_factor + 2 * stack:get_enchantment("projectile_protection")
|
||||
end
|
||||
|
||||
if source.is_fall then
|
||||
protection_factor = protection_factor + 3 * stack:get_enchantment("feather_falling")
|
||||
end
|
||||
end
|
||||
|
||||
if source_object then
|
||||
local thorns_level = stack:get_enchantment("thorns")
|
||||
|
||||
if thorns_level > 0 then
|
||||
local do_irregular_damage = thorns_level > 10
|
||||
|
||||
if do_irregular_damage or thorns_damage_regular < 4 and math.random() < thorns_level * 0.15 then
|
||||
if do_irregular_damage then
|
||||
thorns_damage_irregular = thorns_damage_irregular + thorns_level - 10
|
||||
else
|
||||
thorns_damage_regular = math.min(4, thorns_damage_regular + math.random(4))
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(thorns_pieces, {location = location, stack = stack})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- https://minecraft.gamepedia.com/Armor#Damage_protection
|
||||
damage = damage * (1 - math.min(20, math.max((points / 5), points - damage / (2 + (toughness / 4)))) / 25)
|
||||
|
||||
-- https://minecraft.gamepedia.com/Armor#Enchantments
|
||||
damage = damage * (1 - math.min(20, protection_factor) / 25)
|
||||
|
||||
local thorns_damage = thorns_damage_regular + thorns_damage_irregular
|
||||
|
||||
if thorns_damage > 0 and source_object ~= self then
|
||||
local thorns_damage_source = MCLDamageSource({direct_object = self, source_object = source_object, is_thorns = true})
|
||||
local thorns_knockback = source_object:get_knockback(thorns_damage_source, nil, nil, nil, nil, thorns_damage)
|
||||
|
||||
source_object:damage(thorns_damage, thorns_damage_source, thorns_knockback)
|
||||
|
||||
local piece = thorns_pieces[math.random(#thorns_pieces)]
|
||||
local mclstack = piece.stack
|
||||
mclstack:use_durability(2)
|
||||
equipment[piece.location](equipment, mclstack.stack)
|
||||
end
|
||||
|
||||
return math.floor(damage + 0.5)
|
||||
end
|
||||
|
||||
function MCLObject:base_armor_points()
|
||||
return 0
|
||||
end
|
|
@ -0,0 +1,160 @@
|
|||
local S = minetest.get_translator("mcl_armor")
|
||||
|
||||
mcl_enchanting.enchantments.protection = {
|
||||
name = S("Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_points = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||
weight = 10,
|
||||
description = S("Reduces most types of damage by 4% for each level."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.blast_protection = {
|
||||
name = S("Blast Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_points = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = {fire_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 2,
|
||||
description = S("Reduces explosion damage and knockback."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.fire_protection = {
|
||||
name = S("Fire Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_points = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = {blast_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces fire damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 18}, {18, 26}, {26, 34}, {34, 42}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.projectile_protection = {
|
||||
name = S("Projectile Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_points = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = {blast_protection = true, fire_protection = true, protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces projectile damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.feather_falling = {
|
||||
name = S("Feather Falling"),
|
||||
max_level = 4,
|
||||
primary = {armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 5,
|
||||
description = S("Reduces fall damage."),curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.thorns = {
|
||||
name = S("Thorns"),
|
||||
max_level = 3,
|
||||
primary = {armor_points = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 61}, {30, 71}, {50, 81}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.curse_of_binding = {
|
||||
name = S("Curse of Binding"),
|
||||
max_level = 1,
|
||||
primary = {},
|
||||
secondary = {armor = true},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."),
|
||||
curse = true,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{25, 50}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.frost_walker = {
|
||||
name = S("Frost Walker"),
|
||||
max_level = 2,
|
||||
primary = {},
|
||||
secondary = {boots = true},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {depth_strider = true},
|
||||
weight = 2,
|
||||
description = S("Turns water beneath the player into frosted ice and prevents the damage from magma blocks."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{10, 25}, {20, 35}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
walkover.register_global(function(pos, _, player)
|
||||
local boots = MCLItemStack(mcl_object_mgr.get(player):equipment():boots())
|
||||
if not boots:has_enchantment("frost_walker") then
|
||||
return
|
||||
end
|
||||
local radius = boots:get_enchantment("frost_walker") + 2
|
||||
local minp = {x = pos.x - radius, y = pos.y, z = pos.z - radius}
|
||||
local maxp = {x = pos.x + radius, y = pos.y, z = pos.z + radius}
|
||||
local positions = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:water_source")
|
||||
for _, p in ipairs(positions) do
|
||||
if vector.distance(pos, p) <= radius then
|
||||
minetest.set_node(p, {name = "mcl_core:frosted_ice_0"})
|
||||
end
|
||||
end
|
||||
end)
|
|
@ -1,13 +1,68 @@
|
|||
local S = minetest.get_translator("mcl_armor")
|
||||
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/armor.lua")
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()).."/alias.lua")
|
||||
mcl_armor = {
|
||||
elements = {
|
||||
{
|
||||
name = "helmet",
|
||||
description = S("Helmet"),
|
||||
durability = 0.6875,
|
||||
recipe = function(m)
|
||||
return {
|
||||
{ m, m, m},
|
||||
{ m, "", m},
|
||||
{"", "", ""},
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "chestplate",
|
||||
description = S("Chestplate"),
|
||||
durability = 1.0,
|
||||
recipe = function(m)
|
||||
return {
|
||||
{ m, "", m},
|
||||
{ m, m, m},
|
||||
{ m, m, m},
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "leggings",
|
||||
description = S("Leggings"),
|
||||
durability = 0.9375,
|
||||
recipe = function(m)
|
||||
return {
|
||||
{ m, m, m},
|
||||
{ m, "", m},
|
||||
{ m, "", m},
|
||||
}
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "boots",
|
||||
description = S("Boots"),
|
||||
durability = 0.8125,
|
||||
recipe = function(m)
|
||||
return {
|
||||
{ m, "", m},
|
||||
{ m, "", m},
|
||||
}
|
||||
end,
|
||||
},
|
||||
},
|
||||
longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive."),
|
||||
usagehelp = S("To equip it, put it on the corresponding armor slot in your inventory menu."),
|
||||
}
|
||||
|
||||
local modpath = minetest.get_modpath("mcl_armor")
|
||||
|
||||
dofile(modpath .. "/damage.lua")
|
||||
dofile(modpath .. "/alias.lua")
|
||||
dofile(modpath .. "/items.lua")
|
||||
dofile(modpath .. "/enchantments.lua")
|
||||
|
||||
-- Regisiter Head Armor
|
||||
|
||||
local longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive.")
|
||||
local usage = S("To equip it, put it on the corresponding armor slot in your inventory menu.")
|
||||
|
||||
minetest.register_tool("mcl_armor:helmet_leather", {
|
||||
description = S("Leather Cap"),
|
||||
_doc_items_longdesc = longdesc,
|
||||
|
@ -323,70 +378,3 @@ local craft_ingreds = {
|
|||
diamond = { "mcl_core:diamond" },
|
||||
chain = { nil, "mcl_core:iron_nugget"} ,
|
||||
}
|
||||
|
||||
for k, v in pairs(craft_ingreds) do
|
||||
-- material
|
||||
local m = v[1]
|
||||
-- cooking result
|
||||
local c = v[2]
|
||||
if m ~= nil then
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:helmet_"..k,
|
||||
recipe = {
|
||||
{m, m, m},
|
||||
{m, "", m},
|
||||
{"", "", ""},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:chestplate_"..k,
|
||||
recipe = {
|
||||
{m, "", m},
|
||||
{m, m, m},
|
||||
{m, m, m},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:leggings_"..k,
|
||||
recipe = {
|
||||
{m, m, m},
|
||||
{m, "", m},
|
||||
{m, "", m},
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = "mcl_armor:boots_"..k,
|
||||
recipe = {
|
||||
{m, "", m},
|
||||
{m, "", m},
|
||||
},
|
||||
})
|
||||
end
|
||||
if c ~= nil then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:helmet_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:chestplate_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:leggings_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = c,
|
||||
recipe = "mcl_armor:boots_"..k,
|
||||
cooktime = 10,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
local S = minetest.get_translator("mcl_armor")
|
||||
|
||||
function mcl_armor.register_set(def)
|
||||
local modname = minetest.get_current_modname()
|
||||
local sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_" .. def.material,
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_" .. def.material,
|
||||
}
|
||||
|
||||
for _, elem in pairs(mcl_armor.elements) do
|
||||
local item_name = elem.name .. "_" .. def.name
|
||||
local full_name = modname .. ":" .. item_name
|
||||
|
||||
minetest.register_tool(full_name, {
|
||||
description = def.custom_descriptions[elem.name] or def.description .. " " .. elem.description,
|
||||
_doc_items_longdesc = mcl_armor.longdesc,
|
||||
_doc_items_usagehelp = mcl_armor.usagehelp,
|
||||
inventory_image = modname .. "_inv_" .. item_name .. ".png",
|
||||
groups = {[elem.name] = 1, armor_points = 1, armor = 1, enchantability = def.enchantability}, -- ToDo: armor_points
|
||||
sounds = sounds,
|
||||
on_place = mcl_armor.rightclick_equip,
|
||||
on_secondary_use = mcl_armor.rightclick_equip,
|
||||
_durability = def.durability * elem.durability,
|
||||
_repair_material = def.craft_item,
|
||||
})
|
||||
|
||||
if def.craft_material then
|
||||
minetest.register_craft({
|
||||
output = full_name,
|
||||
recipe = elem.recipe(def.craft_material),
|
||||
})
|
||||
end
|
||||
|
||||
if def.cook_material then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = def.cook_material,
|
||||
recipe = full_name,
|
||||
cooktime = 10,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_armor.register_set {
|
||||
name = "iron",
|
||||
description = S("Iron"),
|
||||
durability = 240,
|
||||
enchantability =
|
||||
craft_material = "mcl_core:iron_ingot",
|
||||
cook_material = "mcl_core:iron_nugget",
|
||||
}
|
|
@ -48,25 +48,6 @@ mcl_enchanting.enchantments.bane_of_arthropods = {
|
|||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.blast_protection = {
|
||||
name = S("Blast Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {fire_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 2,
|
||||
description = S("Reduces explosion damage and knockback."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- requires missing MineClone2 feature
|
||||
--[[mcl_enchanting.enchantments.channeling = {
|
||||
name = S("Channeling"),
|
||||
|
@ -86,25 +67,6 @@ mcl_enchanting.enchantments.blast_protection = {
|
|||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.curse_of_binding = {
|
||||
name = S("Curse of Binding"),
|
||||
max_level = 1,
|
||||
primary = {},
|
||||
secondary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
disallow = {},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Item cannot be removed from armor slots except due to death, breaking or in Creative Mode."),
|
||||
curse = true,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{25, 50}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.curse_of_vanishing = {
|
||||
name = S("Curse of Vanishing"),
|
||||
max_level = 1,
|
||||
|
@ -179,24 +141,6 @@ mcl_enchanting.enchantments.efficiency = {
|
|||
inv_tool_tab = true,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.feather_falling = {
|
||||
name = S("Feather Falling"),
|
||||
max_level = 4,
|
||||
primary = {armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 5,
|
||||
description = S("Reduces fall damage."),curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_mobs and via register_on_punchplayer callback
|
||||
mcl_enchanting.enchantments.fire_aspect = {
|
||||
name = S("Fire Aspect"),
|
||||
|
@ -228,25 +172,6 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch,
|
|||
end
|
||||
end)
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.fire_protection = {
|
||||
name = S("Fire Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, protection = true, projectile_protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces fire damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 18}, {18, 26}, {26, 34}, {34, 42}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
mcl_enchanting.enchantments.flame = {
|
||||
name = S("Flame"),
|
||||
max_level = 1,
|
||||
|
@ -284,42 +209,6 @@ mcl_enchanting.enchantments.fortune = {
|
|||
inv_tool_tab = true,
|
||||
}
|
||||
|
||||
-- implemented via walkover.register_global
|
||||
mcl_enchanting.enchantments.frost_walker = {
|
||||
name = S("Frost Walker"),
|
||||
max_level = 2,
|
||||
primary = {},
|
||||
secondary = {armor_feet = true},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {depth_strider = true},
|
||||
weight = 2,
|
||||
description = S("Turns water beneath the player into frosted ice and prevents the damage from magma blocks."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = true,
|
||||
power_range_table = {{10, 25}, {20, 35}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
walkover.register_global(function(pos, _, player)
|
||||
local boots = player:get_inventory():get_stack("armor", 5)
|
||||
local frost_walker = mcl_enchanting.get_enchantment(boots, "frost_walker")
|
||||
if frost_walker <= 0 then
|
||||
return
|
||||
end
|
||||
local radius = frost_walker + 2
|
||||
local minp = {x = pos.x - radius, y = pos.y, z = pos.z - radius}
|
||||
local maxp = {x = pos.x + radius, y = pos.y, z = pos.z + radius}
|
||||
local positions = minetest.find_nodes_in_area_under_air(minp, maxp, "mcl_core:water_source")
|
||||
for _, p in ipairs(positions) do
|
||||
if vector.distance(pos, p) <= radius then
|
||||
minetest.set_node(p, {name = "mcl_core:frosted_ice_0"})
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- requires missing MineClone2 feature
|
||||
--[[mcl_enchanting.enchantments.impaling = {
|
||||
name = S("Impaling"),
|
||||
|
@ -545,44 +434,6 @@ mcl_enchanting.enchantments.power = {
|
|||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.projectile_protection = {
|
||||
name = S("Projectile Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, fire_protection = true, protection = true},
|
||||
weight = 5,
|
||||
description = S("Reduces projectile damage."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.protection = {
|
||||
name = S("Protection"),
|
||||
max_level = 4,
|
||||
primary = {armor_head = true, armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
secondary = {},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||
weight = 10,
|
||||
description = S("Reduces most types of damage by 4% for each level."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- implemented via minetest.calculate_knockback (together with the Knockback enchantment) and mcl_bows
|
||||
mcl_enchanting.enchantments.punch = {
|
||||
name = S("Punch"),
|
||||
|
@ -754,25 +605,6 @@ mcl_enchanting.enchantments.soul_speed = {
|
|||
inv_tool_tab = false,
|
||||
}]]--
|
||||
|
||||
-- implemented in mcl_armor
|
||||
mcl_enchanting.enchantments.thorns = {
|
||||
name = S("Thorns"),
|
||||
max_level = 3,
|
||||
primary = {armor_head = true},
|
||||
secondary = {armor_torso = true, armor_legs = true, armor_feet = true},
|
||||
disallow = {non_combat_armor = true},
|
||||
incompatible = {},
|
||||
weight = 1,
|
||||
description = S("Reflects some of the damage taken when hit, at the cost of reducing durability with each proc."),
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = false,
|
||||
power_range_table = {{10, 61}, {30, 71}, {50, 81}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- for tools & weapons implemented via on_enchant; for bows implemented in mcl_bows; for armor implemented in mcl_armor and mcl_tt; for fishing rods implemented in mcl_fishing
|
||||
mcl_enchanting.enchantments.unbreaking = {
|
||||
name = S("Unbreaking"),
|
||||
|
|
Loading…
Reference in New Issue