From 9ce59d4438b55b4edf19c2bafca7b038e2902841 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 17 Mar 2021 15:21:27 +0100 Subject: [PATCH] Rework armor (WIP) --- mods/CORE/mcl_armor/init.lua | 118 --------------- mods/CORE/mcl_damage_source/init.lua | 9 +- mods/CORE/mcl_entity/init.lua | 18 --- mods/CORE/mcl_equipment/init.lua | 2 +- mods/CORE/mcl_itemstack/init.lua | 16 +- mods/CORE/mcl_mob/init.lua | 6 +- mods/CORE/mcl_object/init.lua | 55 ++++--- mods/CORE/mcl_player/init.lua | 10 ++ mods/ITEMS/mcl_armor/armor.lua | 4 +- mods/ITEMS/mcl_armor/damage.lua | 105 +++++++++++++ mods/ITEMS/mcl_armor/enchantments.lua | 160 ++++++++++++++++++++ mods/ITEMS/mcl_armor/init.lua | 134 ++++++++-------- mods/ITEMS/mcl_armor/items.lua | 52 +++++++ mods/ITEMS/mcl_enchanting/enchantments.lua | 168 --------------------- 14 files changed, 446 insertions(+), 411 deletions(-) delete mode 100644 mods/CORE/mcl_armor/init.lua create mode 100644 mods/ITEMS/mcl_armor/damage.lua create mode 100644 mods/ITEMS/mcl_armor/enchantments.lua create mode 100644 mods/ITEMS/mcl_armor/items.lua diff --git a/mods/CORE/mcl_armor/init.lua b/mods/CORE/mcl_armor/init.lua deleted file mode 100644 index e332fcda3c..0000000000 --- a/mods/CORE/mcl_armor/init.lua +++ /dev/null @@ -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 ) - 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 diff --git a/mods/CORE/mcl_damage_source/init.lua b/mods/CORE/mcl_damage_source/init.lua index c0fbc9dfed..0c15a26537 100644 --- a/mods/CORE/mcl_damage_source/init.lua +++ b/mods/CORE/mcl_damage_source/init.lua @@ -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) diff --git a/mods/CORE/mcl_entity/init.lua b/mods/CORE/mcl_entity/init.lua index 0c74f8fba9..ad1db38cd1 100644 --- a/mods/CORE/mcl_entity/init.lua +++ b/mods/CORE/mcl_entity/init.lua @@ -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 diff --git a/mods/CORE/mcl_equipment/init.lua b/mods/CORE/mcl_equipment/init.lua index 03e1cd8084..6a9d2ec7d5 100644 --- a/mods/CORE/mcl_equipment/init.lua +++ b/mods/CORE/mcl_equipment/init.lua @@ -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) diff --git a/mods/CORE/mcl_itemstack/init.lua b/mods/CORE/mcl_itemstack/init.lua index 38111d174c..c53e4301a6 100644 --- a/mods/CORE/mcl_itemstack/init.lua +++ b/mods/CORE/mcl_itemstack/init.lua @@ -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 diff --git a/mods/CORE/mcl_mob/init.lua b/mods/CORE/mcl_mob/init.lua index 169db4c9f6..71d75bf5b0 100644 --- a/mods/CORE/mcl_mob/init.lua +++ b/mods/CORE/mcl_mob/init.lua @@ -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 diff --git a/mods/CORE/mcl_object/init.lua b/mods/CORE/mcl_object/init.lua index 9666a436b5..f84c19c008 100644 --- a/mods/CORE/mcl_object/init.lua +++ b/mods/CORE/mcl_object/init.lua @@ -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 diff --git a/mods/CORE/mcl_player/init.lua b/mods/CORE/mcl_player/init.lua index db93933cd0..c8dc0f721d 100644 --- a/mods/CORE/mcl_player/init.lua +++ b/mods/CORE/mcl_player/init.lua @@ -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 diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua index ec06f19ee1..ee38c032af 100644 --- a/mods/ITEMS/mcl_armor/armor.lua +++ b/mods/ITEMS/mcl_armor/armor.lua @@ -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 diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua new file mode 100644 index 0000000000..9c45289256 --- /dev/null +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -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 diff --git a/mods/ITEMS/mcl_armor/enchantments.lua b/mods/ITEMS/mcl_armor/enchantments.lua new file mode 100644 index 0000000000..c0796cdf55 --- /dev/null +++ b/mods/ITEMS/mcl_armor/enchantments.lua @@ -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) diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index c5502cf424..2905aaa43f 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -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, @@ -322,71 +377,4 @@ local craft_ingreds = { gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" }, 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 - +} diff --git a/mods/ITEMS/mcl_armor/items.lua b/mods/ITEMS/mcl_armor/items.lua new file mode 100644 index 0000000000..1d8bc98a5e --- /dev/null +++ b/mods/ITEMS/mcl_armor/items.lua @@ -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", +} diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 2f26b8eacc..7cb9d984f4 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -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"),