From ce0148d9a86463b2a34bce0a145f7fc324015f88 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 15:46:52 +0200 Subject: [PATCH 01/43] Rewrite armor; new damage system --- mods/CORE/mcl_damage/init.lua | 107 +++ mods/CORE/mcl_damage/mod.conf | 3 + mods/CORE/mcl_explosions/init.lua | 38 +- mods/CORE/mcl_util/init.lua | 96 +++ mods/ENTITIES/mcl_burning/api.lua | 8 +- mods/ENTITIES/mcl_mobs/api.lua | 6 +- mods/ENTITIES/mobs_mc/blaze.lua | 4 +- mods/ENTITIES/mobs_mc/ghast.lua | 20 +- mods/HUD/mcl_experience/init.lua | 29 +- mods/HUD/mcl_hbarmor/init.lua | 9 +- mods/HUD/mcl_inventory/creative.lua | 29 +- mods/HUD/mcl_inventory/init.lua | 51 +- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 7 +- mods/ITEMS/mcl_armor/api.lua | 232 ++++++ mods/ITEMS/mcl_armor/armor.lua | 675 ------------------ mods/ITEMS/mcl_armor/damage.lua | 103 +++ mods/ITEMS/mcl_armor/init.lua | 464 ++---------- mods/ITEMS/mcl_armor/player.lua | 143 ++++ mods/ITEMS/mcl_armor/register.lua | 204 ++++++ mods/ITEMS/mcl_armor_stand/init.lua | 4 +- mods/ITEMS/mcl_bows/arrow.lua | 4 +- mods/ITEMS/mcl_bows/bow.lua | 1 + mods/ITEMS/mcl_core/nodes_liquid.lua | 2 +- mods/ITEMS/mcl_enchanting/enchantments.lua | 151 ---- mods/ITEMS/mcl_enchanting/engine.lua | 3 +- mods/ITEMS/mcl_farming/pumpkin.lua | 6 +- mods/ITEMS/mcl_fire/init.lua | 4 +- mods/ITEMS/mcl_heads/init.lua | 2 +- mods/ITEMS/mcl_potions/functions.lua | 15 +- mods/ITEMS/mcl_torches/api.lua | 2 +- mods/ITEMS/screwdriver/init.lua | 2 +- mods/PLAYER/mcl_death_drop/init.lua | 4 +- mods/PLAYER/mcl_player/init.lua | 47 +- mods/PLAYER/mcl_playerplus/init.lua | 12 +- mods/PLAYER/mcl_skins/init.lua | 7 +- mods/PLAYER/mcl_skins/mod.conf | 2 +- .../{wieldview => mcl_wieldview}/LICENSE.txt | 0 .../{wieldview => mcl_wieldview}/README.txt | 0 mods/PLAYER/mcl_wieldview/init.lua | 122 ++++ .../{wieldview => mcl_wieldview}/mod.conf | 5 +- mods/PLAYER/wieldview/init.lua | 132 ---- mods/PLAYER/wieldview/transform.lua | 10 - 42 files changed, 1203 insertions(+), 1562 deletions(-) create mode 100644 mods/CORE/mcl_damage/init.lua create mode 100644 mods/CORE/mcl_damage/mod.conf create mode 100644 mods/ITEMS/mcl_armor/api.lua delete mode 100644 mods/ITEMS/mcl_armor/armor.lua create mode 100644 mods/ITEMS/mcl_armor/damage.lua create mode 100644 mods/ITEMS/mcl_armor/player.lua create mode 100644 mods/ITEMS/mcl_armor/register.lua rename mods/PLAYER/{wieldview => mcl_wieldview}/LICENSE.txt (100%) rename mods/PLAYER/{wieldview => mcl_wieldview}/README.txt (100%) create mode 100644 mods/PLAYER/mcl_wieldview/init.lua rename mods/PLAYER/{wieldview => mcl_wieldview}/mod.conf (66%) delete mode 100644 mods/PLAYER/wieldview/init.lua delete mode 100644 mods/PLAYER/wieldview/transform.lua diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua new file mode 100644 index 000000000..bd640be43 --- /dev/null +++ b/mods/CORE/mcl_damage/init.lua @@ -0,0 +1,107 @@ +mcl_damage = { + modifiers = {}, + types = { + in_fire = {is_fire = true}, + lightning_bolt = {is_lightning = true}, + on_fire = {is_fire = true}, + lava = {is_fire = true}, + hot_floor = {is_fire = true}, + in_wall = {bypasses_armor = true}, + drown = {bypasses_armor = true}, + starve = {bypasses_armor = true, bypasses_magic = true}, + cactus = {}, + fall = {bypasses_armor = true}, + fly_into_wall = {bypasses_armor = true}, -- unused + out_of_world = {bypasses_armor = true, bypasses_invulnerability = true, bypasses_magic = true}, + generic = {bypasses_armor = true}, + magic = {is_magic = true, bypasses_armor = true}, + wither = {bypasses_armor = true}, -- unused + anvil = {}, + falling_node = {}, -- unused + dragon_breath = {bypasses_armor = true}, -- unused + mob = {}, + player = {}, + arrow = {is_projectile = true}, + fireball = {is_projectile = true, is_fire = true}, + thorns = {is_magic = true}, + explosion = {is_explosion = true}, + } +} + +local old_register_hpchange = minetest.register_on_player_hpchange + +function minetest.register_on_player_hpchange(func, modifier) + if modifier then + mcl_damage.register_modifier(func, 0) + else + old_register_hpchange(func, modifier) + end +end + +function mcl_damage.register_modifier(func, priority) + table.insert(mcl_damage, {func = func, priority = priority or 0}) +end + +function mcl_damage.get_mcl_damage_reason(mt_reason) + local mcl_reason = { + type = "generic", + } + + if mt_reason._mcl_type then + mcl_reason.type = mt_reason._mcl_type + elseif mt_reason.type == "fall" then + mcl_reason.type = "fall" + elseif mt_reason.type == "drown" then + mcl_reason.type = "drown" + elseif mt_reason.type == "punch" then + mcl_reason.direct = mt_reason.object + if mcl_reason.direct then + local luaentity = mcl_reason.direct:get_luaentity() + if luaentity then + if luaentity._is_arrow then + mcl_reason.type = "arrow" + elseif luaentity._is_fireball then + mcl_reason.type = "fireball" + elseif luaentity._cmi_is_mob then + mcl_reason.type = "mob" + end + mcl_reason.source = mcl_reason.source or luaentity._source_object + else + mcl_reason.type = "player" + end + end + elseif mt_reason.type == "node_damage" then + if minetest.get_item_group(reason.node or "", "fire_damage") > 0 then + mcl_reason.type = "in_fire" + end + end + + for key, value in pairs(mt_reason) do + if key:find("_mcl_") == 1 then + mcl_reason[key:sub(6, #key)] = value + end + end + + mcl_reason.source = mcl_reason.source or mcl_reason.direct + + mcl_reason.flags = mcl_damage.types[mcl_reason.type] +end + +function mcl_damage.register_type(name, def) + mcl_damage.types[name] = def +end + +old_register_hpchange(function(player, hp_change, mt_reason) + local mcl_reason = mcl_damage.get_mcl_damage_reason(mt_reason) + + for _, modf in ipairs(mcl_damage.modifiers) do + hp_change = modf.func(player, hp_change, mt_reason, mcl_reason) or hp_change + end + + return hp_change +end, true) + +minetest.register_on_mods_loaded(function() + table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) +end) + diff --git a/mods/CORE/mcl_damage/mod.conf b/mods/CORE/mcl_damage/mod.conf new file mode 100644 index 000000000..c7d96395e --- /dev/null +++ b/mods/CORE/mcl_damage/mod.conf @@ -0,0 +1,3 @@ +name = mcl_damage +author = Fleckenstein +description = Minecraft-like damage reason system diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 34375248e..bc1970f6b 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -150,7 +150,8 @@ end -- raydirs - The directions for each ray -- radius - The maximum distance each ray will go -- info - Table containing information about explosion --- puncher - object that punches other objects (optional) +-- direct - direct source object of the damage (optional) +-- source - indirect source object of the damage (optional) -- -- Values in info: -- drop_chance - The chance that destroyed nodes will drop their items @@ -165,7 +166,7 @@ end -- Note that this function has been optimized, it contains code which has been -- inlined to avoid function calls and unnecessary table creation. This was -- measured to give a significant performance increase. -local function trace_explode(pos, strength, raydirs, radius, info, puncher) +local function trace_explode(pos, strength, raydirs, radius, info, direct, source) local vm = get_voxel_manip() local emin, emax = vm:read_from_map(vector.subtract(pos, radius), @@ -247,7 +248,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) local ent = obj:get_luaentity() -- Ignore items to lower lag - if obj:is_player() or (ent and ent.name ~= '__builtin.item') then + if (obj:is_player() or (ent and ent.name ~= '__builtin.item')) and obj:get_hp() > 0 then local opos = obj:get_pos() local collisionbox = nil @@ -321,7 +322,6 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) impact = 0 end local damage = math.floor((impact * impact + impact) * 7 * strength + 1) - local source = puncher or obj local sleep_formspec_doesnt_close_mt53 = false if obj:is_player() then @@ -336,23 +336,22 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) 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 if sleep_formspec_doesnt_close_mt53 then - minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE - if not obj then return end - obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) - obj:add_velocity(vector.multiply(punch_dir, impact * 20)) - end, obj, damage, impact, vector.new(punch_dir)) - else - obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) + minetest.after(0.3, function() -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE + if not obj:is_player() then + return + end + + mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source}) - if obj:is_player() then obj:add_velocity(vector.multiply(punch_dir, impact * 20)) - elseif ent.tnt_knockback then + end) + else + mcl_util.deal_damage(obj, damage, {type = "explosion", direct = direct, source = source}) + + if obj:is_player() or ent.tnt_knockback then obj:add_velocity(vector.multiply(punch_dir, impact * 20)) end end @@ -422,7 +421,8 @@ end -- pos - The position where the explosion originates from -- strength - The blast strength of the explosion (a TNT explosion uses 4) -- info - Table containing information about explosion --- puncher - object that is reported as source of punches/damage (optional) +-- direct - direct source object of the damage (optional) +-- source - indirect source object of the damage (optional) -- -- Values in info: -- drop_chance - If specified becomes the drop chance of all nodes in the @@ -436,7 +436,7 @@ end -- griefing - If true, the explosion will destroy nodes (default: true) -- grief_protected - If true, the explosion will also destroy nodes which have -- been protected (default: false) -function mcl_explosions.explode(pos, strength, info, puncher) +function mcl_explosions.explode(pos, strength, info, direct, source) if info == nil then info = {} end @@ -465,7 +465,7 @@ function mcl_explosions.explode(pos, strength, info, puncher) info.drop_chance = 0 end - trace_explode(pos, strength, shape, radius, info, puncher) + trace_explode(pos, strength, shape, radius, info, direct, source) if info.particles then add_particles(pos, radius) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index ac913de39..55f308602 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -418,3 +418,99 @@ function mcl_util.get_color(colorstr) return colorstr, hex end end + +function mcl_util.call_on_rightclick(itemstack, player, pointed_thing) + -- Call on_rightclick if the pointed node defines it + if pointed_thing and pointed_thing.type == "node" then + local node = minetest.get_node(pointed_thing.under) + if player and not player:get_player_control().sneak then + if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then + return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + end + end + end +end + +function mcl_util.calculate_durability(itemstack) + local unbreaking_level = mcl_enchanting.get_enchantment(itemstack, "unbreaking") + local armor_uses = minetest.get_item_group(itemstack:get_name(), "mcl_armor_uses") + + local uses + + if armor_uses > 0 then + uses = armor_uses + if unbreaking_level > 0 then + uses = uses / (0.6 + 0.4 / (unbreaking_level + 1)) + end + else + local def = itemstack:get_definition() + if def then + local fixed_uses = def._mcl_uses + if fixed_uses then + uses = fixed_uses + if unbreaking_level > 0 then + uses = uses * (unbreaking_level + 1) + end + end + end + if not uses then + local toolcaps = itemstack:get_tool_capabilities() + local groupcaps = toolcaps.groupcaps + for _, v in pairs(groupcaps) do + uses = v.uses + break + end + end + end + + return uses or 0 +end + +function mcl_util.use_item_durability(itemstack, n) + local uses = mcl_util.calculate_durability(itemstack) + itemstack:add_wear(65535 / uses * n) +end + +function mcl_util.deal_damage(target, damage, mcl_reason) + mcl_reason = mcl_reason or {} + + local luaentity = target:get_luaentity() + + if luaentity then + if luaentity.deal_damage then + luaentity:deal_damage(damage, mcl_reason) + return + elseif luaentity._cmi_is_mob then + local puncher = mcl_reason.direct or target + target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage) + return + end + end + + local mt_reason + + if target:is_player() then + mt_reason = {} + + for key, value in pairs(mcl_reason) do + mt_reason["_mcl_" .. key] = value + end + end + + target:set_hp(target:get_hp() - damage, mt_reason) +end + +function mcl_util.get_inventory(object, create) + if object:is_player() then + return object:get_inventory() + else + local luaentity = object:get_luaentity() + local inventory = luaentity.inventory + + if create and not inventory and luaentity.create_inventory then + inventory = luaentity:create_inventory() + end + + return inventory + end +end diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index b08a0fb70..98f315ef9 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -92,7 +92,6 @@ function mcl_burning.damage(obj) do_damage = false else local name = obj:get_player_name() - armor.last_damage_types[name] = "fire" local deathmsg = S("@1 burned to death.", name) local reason = mcl_burning.get(obj, "string", "reason") if reason ~= "" then @@ -107,12 +106,7 @@ function mcl_burning.damage(obj) end if do_damage then - local new_hp = hp - 1 - if health then - luaentity.health = new_hp - else - obj:set_hp(new_hp) - end + mcl_util.deal_damage(obj, 1, {type = "in_fire"}) end end diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 6c1a0567e..75f42d92a 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -177,7 +177,7 @@ local function object_in_range(self, object) local factor -- Apply view range reduction for special player armor if object:is_player() and mod_armor then - factor = armor:get_mob_view_range_factor(object, self.name) + factor = mcl_armor.get_mob_view_range_factor(object, self.name) end -- Distance check local dist @@ -3906,7 +3906,7 @@ minetest.register_entity(name, { --default built in engine collision detection self.object:set_properties({ collide_with_objects = false, - }) + }) return mob_activate(self, staticdata, def, dtime) end, @@ -4367,4 +4367,4 @@ minetest.register_globalstep(function(dtime) end timer = 0 end) -]]-- \ No newline at end of file +]]-- diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 847e2f4a5..4595ce5a7 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -147,12 +147,10 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { visual_size = {x = 0.3, y = 0.3}, textures = {"mcl_fire_fire_charge.png"}, velocity = 15, + _is_fireball = true, -- Direct hit, no fire... just plenty of pain 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 mcl_burning.set_on_fire(player, 5, "blaze") player:punch(self.object, 1.0, { full_punch_interval = 1.0, diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 83a10bfc4..48d71b45e 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -76,18 +76,18 @@ mobs:register_mob("mobs_mc:ghast", { mobs:spawn_specific( -"mobs_mc:ghast", -"nether", +"mobs_mc:ghast", +"nether", "ground", { "Nether" }, -0, -minetest.LIGHT_MAX+1, -30, -18000, -2, -mobs_mc.spawn_height.nether_min, +0, +minetest.LIGHT_MAX+1, +30, +18000, +2, +mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- fireball (projectile) @@ -97,11 +97,9 @@ mobs:register_arrow("mobs_mc:fireball", { textures = {"mcl_fire_fire_charge.png"}, velocity = 15, collisionbox = {-.5, -.5, -.5, .5, .5, .5}, + _is_fireball = true, 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, { full_punch_interval = 1.0, damage_groups = {fleshy = 6}, diff --git a/mods/HUD/mcl_experience/init.lua b/mods/HUD/mcl_experience/init.lua index df733e138..47db77bca 100644 --- a/mods/HUD/mcl_experience/init.lua +++ b/mods/HUD/mcl_experience/init.lua @@ -263,34 +263,7 @@ function mcl_experience.add_experience(player, experience) local can = final_candidates[math.random(#final_candidates)] local stack, list, index, wear = can.stack, can.list, can.index, can.wear local unbreaking_level = mcl_enchanting.get_enchantment(stack, "unbreaking") - local uses - local armor_uses = minetest.get_item_group(stack:get_name(), "mcl_armor_uses") - if armor_uses > 0 then - uses = armor_uses - if unbreaking_level > 0 then - uses = uses / (0.6 + 0.4 / (unbreaking_level + 1)) - end - else - local def = stack:get_definition() - if def then - local fixed_uses = def._mcl_uses - if fixed_uses then - uses = fixed_uses - if unbreaking_level > 0 then - uses = uses * (unbreaking_level + 1) - end - end - end - if not uses then - local toolcaps = stack:get_tool_capabilities() - local groupcaps = toolcaps.groupcaps - for _, v in pairs(groupcaps) do - uses = v.uses - break - end - end - end - uses = uses or 0 + local uses = mcl_util.calculate_durability(itemstack) local multiplier = 2 * 65535 / uses local repair = experience * multiplier local new_wear = wear - repair diff --git a/mods/HUD/mcl_hbarmor/init.lua b/mods/HUD/mcl_hbarmor/init.lua index 89b2db7a8..9e5aa634b 100644 --- a/mods/HUD/mcl_hbarmor/init.lua +++ b/mods/HUD/mcl_hbarmor/init.lua @@ -1,9 +1,5 @@ local S = minetest.get_translator("mcl_hbarmor") -if (not armor) or (not armor.def) then - minetest.log("error", "[mcl_hbarmor] Outdated mcl_armor version. Please update your version of mcl_armor!") -end - local mcl_hbarmor = {} -- HUD statbar values @@ -60,11 +56,8 @@ end hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide) function mcl_hbarmor.get_armor(player) - if not player or not armor.def then - return false - end local name = player:get_player_name() - local pts = armor:get_armor_points(player) + local pts = player:get_meta():get_int("mcl_armor:armor_points") if not pts then return false else diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index a69fcef5b..4f6144d15 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -7,8 +7,7 @@ local players = {} -- Containing all the items for each Creative Mode tab local inventory_lists = {} -local show_armor = minetest.get_modpath("mcl_armor") ~= nil -local mod_player = minetest.get_modpath("mcl_player") ~= nil ++local mod_player = minetest.get_modpath("mcl_player") ~= nil -- Create tables local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} @@ -334,23 +333,7 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz if minetest.settings:get_bool("3d_player_preview", true) then player_preview = mcl_player.get_player_formspec_model(player, 3.9, 1.4, 1.2333, 2.4666, "") else - local img, img_player - if mod_player then - img_player = mcl_player.player_get_preview(player) - else - img_player = "player.png" - end - img = img_player - player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]" - if show_armor and armor.textures[playername] and armor.textures[playername].preview then - img = armor.textures[playername].preview - local s1 = img:find("character_preview") - if s1 ~= nil then - s1 = img:sub(s1+21) - img = img_player..s1 - end - player_preview = "image[3.9,1.4;1.2333,2.4666;"..img.."]" - end + player_preview = "image[3.9,1.4;1.2333,2.4666;"..mcl_player.player_get_preview(player).."]" end -- Background images for armor slots (hide if occupied) @@ -373,10 +356,10 @@ mcl_inventory.set_creative_formspec = function(player, start_i, pagenum, inv_siz main_list = "list[current_player;main;0,3.75;9,3;9]".. mcl_formspec.get_itemslot_bg(0,3.75,9,3).. -- armor - "list[detached:"..playername.."_armor;armor;2.5,1.3;1,1;1]".. - "list[detached:"..playername.."_armor;armor;2.5,2.75;1,1;2]".. - "list[detached:"..playername.."_armor;armor;5.5,1.3;1,1;3]".. - "list[detached:"..playername.."_armor;armor;5.5,2.75;1,1;4]".. + "list[current_player;armor;2.5,1.3;1,1;1]".. + "list[current_player;armor;2.5,2.75;1,1;2]".. + "list[current_player;armor;5.5,1.3;1,1;3]".. + "list[current_player;armor;5.5,2.75;1,1;4]".. mcl_formspec.get_itemslot_bg(2.5,1.3,1,1).. mcl_formspec.get_itemslot_bg(2.5,2.75,1,1).. mcl_formspec.get_itemslot_bg(5.5,1.3,1,1).. diff --git a/mods/HUD/mcl_inventory/init.lua b/mods/HUD/mcl_inventory/init.lua index e9da9486e..dccf81bb4 100644 --- a/mods/HUD/mcl_inventory/init.lua +++ b/mods/HUD/mcl_inventory/init.lua @@ -3,7 +3,6 @@ local F = minetest.formspec_escape mcl_inventory = {} -local show_armor = minetest.get_modpath("mcl_armor") ~= nil local mod_player = minetest.get_modpath("mcl_player") ~= nil local mod_craftguide = minetest.get_modpath("mcl_craftguide") ~= nil @@ -68,23 +67,7 @@ local function set_inventory(player, armor_change_only) if minetest.settings:get_bool("3d_player_preview", true) then player_preview = mcl_player.get_player_formspec_model(player, 1.0, 0.0, 2.25, 4.5, "") else - local img, img_player - if mod_player then - img_player = mcl_player.player_get_preview(player) - else - img_player = "player.png" - end - img = img_player - player_preview = "image[0.6,0.2;2,4;"..img.."]" - if show_armor and armor.textures[player_name] and armor.textures[player_name].preview then - img = armor.textures[player_name].preview - local s1 = img:find("character_preview") - if s1 ~= nil then - s1 = img:sub(s1+21) - img = img_player..s1 - end - player_preview = "image[1.1,0.2;2,4;"..img.."]" - end + player_preview = "image[1.1,0.2;2,4;"..mcl_player.player_get_preview(player).."]" end local armor_slots = {"helmet", "chestplate", "leggings", "boots"} @@ -99,10 +82,10 @@ local function set_inventory(player, armor_change_only) "background[-0.19,-0.25;9.41,9.49;crafting_formspec_bg.png]".. player_preview.. --armor - "list[detached:"..player_name.."_armor;armor;0,0;1,1;1]".. - "list[detached:"..player_name.."_armor;armor;0,1;1,1;2]".. - "list[detached:"..player_name.."_armor;armor;0,2;1,1;3]".. - "list[detached:"..player_name.."_armor;armor;0,3;1,1;4]".. + "list[current_player;armor;0,0;1,1;1]".. + "list[current_player;armor;0,1;1,1;2]".. + "list[current_player;armor;0,2;1,1;3]".. + "list[current_player;armor;0,3;1,1;4]".. mcl_formspec.get_itemslot_bg(0,0,1,1).. mcl_formspec.get_itemslot_bg(0,1,1,1).. mcl_formspec.get_itemslot_bg(0,2,1,1).. @@ -133,10 +116,10 @@ local function set_inventory(player, armor_change_only) "tooltip[__mcl_achievements;"..F(S("Achievements")).."]".. -- for shortcuts "listring[current_player;main]".. - "listring[current_player;craft]".. - "listring[current_player;main]".. - "listring[detached:"..player_name.."_armor;armor]" - + "listring[current_player;armor]".. + "listring[current_player;main]" .. + "listring[current_player;craft]" .. + "listring[current_player;main]" player:set_inventory_formspec(form) end @@ -176,18 +159,10 @@ minetest.register_on_joinplayer(function(player) player:hud_set_hotbar_image("mcl_inventory_hotbar.png") player:hud_set_hotbar_selected_image("mcl_inventory_hotbar_selected.png") - if show_armor then - local set_player_armor_original = armor.set_player_armor - local update_inventory_original = armor.update_inventory - armor.set_player_armor = function(self, player) - set_player_armor_original(self, player) - end - armor.update_inventory = function(self, player) - update_inventory_original(self, player) - set_inventory(player, true) - end - armor:set_player_armor(player) - armor:update_inventory(player) + local old_update_player = mcl_armor.update_player + mcl_armor.update_player = function(player, info) + old_update_player(player, info) + set_inventory(player, true) end -- In Creative Mode, the initial inventory setup is handled in creative.lua diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index 1fd63cb4d..ace2c6464 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -170,7 +170,7 @@ local dispenserdef = { minetest.registered_nodes["mcl_armor_stand:armor_stand"].on_metadata_inventory_put(standpos) stack:take_item() inv:set_stack("main", stack_id, stack) - armor:play_equip_sound(dropitem, nil, standpos) + mcl_armor.play_equip_sound(dropitem, nil, standpos) armor_dispensed = true end else @@ -202,9 +202,8 @@ local dispenserdef = { if ainv:get_stack("armor", armor_slot):is_empty() and pinv:get_stack("armor", armor_slot):is_empty() then ainv:set_stack("armor", armor_slot, dropitem) pinv:set_stack("armor", armor_slot, dropitem) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(dropitem, player) + mcl_armor.update(player) + mcl_armor.play_equip_sound(dropitem, player) stack:take_item() inv:set_stack("main", stack_id, stack) diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua new file mode 100644 index 000000000..3f0641a54 --- /dev/null +++ b/mods/ITEMS/mcl_armor/api.lua @@ -0,0 +1,232 @@ +function mcl_armor.play_equip_sound(stack, obj, pos, unequip) + local def = stack:get_definition() + local estr = "equip" + if unequip then + estr = "unequip" + end + local snd = def.sounds and def.sounds["_mcl_armor_" .. estr] + if not snd then + -- Fallback sound + snd = { name = "mcl_armor_" .. estr .. "_generic" } + end + if snd then + local dist = 8 + if pos then + dist = 16 + end + minetest.sound_play(snd, {object = obj, pos = pos, gain = 0.5, max_hear_distance = dist}, true) + end +end + +function mcl_armor.equip(itemstack, obj) + local def = itemstack:get_definition() + local element = mcl_armor.elements[def._mcl_armor_element or ""] + local inv = mcl_util.get_inventory(obj) + + if element and inv then + if inv:get_stack("armor", element.index):is_empty() then + local equipping_item = itemstack:take_item() + inv:set_stack("armor", element.index, equipping_item) + if def._on_equip then + def._on_equip(equipping_item) + end + mcl_armor.update(obj) + end + end + + return itemstack +end + +function mcl_armor.equip_on_use(itemstack, player, pointed_thing) + if not player or not player:is_player() then + return itemstack + end + + local new_stack = mcl_util.call_on_rightclick(itemstack, player, pointed_thing) + if new_stack then + return new_stack + end + + return mcl_armor.equip(itemstack, player) +end + +function mcl_armor.register_set(def) + local modname = minetest.get_current_modname() + local S = minetest.get_translator(modname) + local descriptions = def.descriptions or {} + local groups = def.groups or {} + for name, element in pairs(mcl_armor.elements) do + local itemname = element.name .. "_" .. def.name + local itemstring = modname .. ":" .. itemname + + local groups = table.copy(groups) + groups["armor_" .. name] = 1 + groups["combat_armor_" .. name] = 1 + groups.armor = 1 + groups.combat_armor = 1 + groups.mcl_armor_points = def.points[name] + groups.mcl_armor_toughness = def.toughness + groups.mcl_armor_uses = math.floor(def.durability * element.durability) + 1 + groups.enchantability = def.enchantability + + minetest.register_tool(itemstring, { + description = S(def.description .. " " .. (descriptions[name] or element.description)), + _doc_items_longdesc = mcl_armor.longdesc, + _doc_items_usagehelp = mcl_armor.usage, + inventory_image = modname .. "_inv_" .. itemname .. ".png", + _repair_material = def.repair_material or def.craft_material, + groups = groups, + sounds = { + _mcl_armor_equip = def.sound_equip or modname .. "_equip_" .. def.name, + _mcl_armor_unequip = def.sound_unequip or modname .. "_unequip_" .. def.name, + }, + on_place = mcl_armor.equip_on_use, + on_secondary_use = mcl_armor.equip_on_use, + _on_equip = def.on_equip, + _on_unequip = def.on_unequip, + _mcl_armor_element = name, + _mcl_armor_texture = modname .. "_" .. itemname .. ".png", + _mcl_armor_preview = modname .. "_" .. itemname .. "_preview.png", + }) + + if def.craft_material then + minetest.register_craft({ + output = itemstring, + recipe = element.craft(def.craft_material), + }) + end + + if def.cook_material then + minetest.register_craft({ + type = "cooking", + output = def.cook_material, + recipe = itemstring, + cooktime = 10, + }) + end + end +end + +mcl_armor.protection_enchantments = { + flags = {}, + types = {}, + wildcard = {}, +} + +function mcl_armor.register_protection_enchantment(def) + local prot_def = {id = def.id, factor = def.factor} + if def.damage_flag then + local tbl = mcl_armor.protection_enchantments.flags[def.damage_flag] or {} + table.insert(tbl, prot_def) + mcl_armor.protection_enchantments.flags = tbl + elseif def.damage_type then + local tbl = mcl_armor.protection_enchantments.types[def.damage_type] or {} + table.insert(tbl, prot_def) + mcl_armor.protection_enchantments.types = tbl + else + table.insert(mcl_armor.protection_enchantments.wildcard, prot_def) + end + mcl_enchanting.enchantments[def.id] = { + name = def.name, + max_level = def.max_level or 4, + primary = def.primary or {combat_armor = true}, + secondary = {}, + disallow = {}, + incompatible = def.incompatible or {}, + weight = def.weight or 5, + description = def.description, + curse = false, + on_enchant = function() end, + requires_tool = false, + treasure = def.treasure or false, + power_range_table = def.power_range_table, + inv_combat_tab = true, + inv_tool_tab = false, + } +end + +function mcl_armor.get_armor_points(obj) + local points = 0 + local inv = mcl_util.get_inventory(obj) + if inv then + for i = 2, 5 do + local itemstack = inv:get_stack("armor", i) + if not itemstack:is_empty() then + points = points + minetest.get_item_group(itemstack:get_name(), "mcl_armor_points") + end + end + end + return points +end + +-- Returns a change factor for a mob's view_range for the given object +-- or nil, if there's no change. Certain armors (like mob heads) can +-- affect the view range of mobs. +function mcl_armor.get_mob_view_range_factor(obj, mob) + local inv = mcl_util.get_inventory(obj) + local factor + if inv then + for i = 2, 5 do + local itemstack = inv:get_stack("armor", i) + if not itemstack:is_empty() then + local def = itemstack:get_definition() + if def._mcl_armor_mob_range_mob == mob then + if not factor then + factor = def._mcl_armor_mob_range_factor + elseif factor == 0 then + return 0 + else + factor = factor * def._mcl_armor_mob_range_factor + end + end + end + end + end + return factor +end + +function mcl_armor.update(obj) + local info = {points = 0} + + local inv = mcl_util.get_inventory(obj) + + if inv then + for i = 2, 5 do + local itemstack = inv:get_stack("armor", i) + + local itemname = itemstack:get_name() + if minetest.registered_aliases[itemname] then + itemname = minetest.registered_aliases[itemname] + end + + if not itemstack:is_empty() then + local def = itemstack:get_definition() + + if def._mcl_armor_texture then + info.texture = "(" .. def._mcl_armor_texture .. ")" .. (info.texture and "^" .. info.texture or "") + end + + if obj:is_player() and def._mcl_armor_preview then + info.preview = "(player.png^[opacity:0^" .. def._mcl_armor_preview .. ")" .. (info.preview and "^" .. info.preview or "" ) + end + + info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points") + end + end + end + + info.texture = info.texture or "blank.png" + + if obj:is_player() then + info.preview = info.preview or "blank.png" + + mcl_armor.update_player(obj, info) + else + local luaentity = obj:get_luaentity() + + if luaentity.update_armor then + luaentity:update_armor(info) + end + end +end + diff --git a/mods/ITEMS/mcl_armor/armor.lua b/mods/ITEMS/mcl_armor/armor.lua deleted file mode 100644 index a35841fe2..000000000 --- a/mods/ITEMS/mcl_armor/armor.lua +++ /dev/null @@ -1,675 +0,0 @@ -local ARMOR_INIT_DELAY = 1 -local ARMOR_INIT_TIMES = 1 -local ARMOR_BONES_DELAY = 1 - -local skin_mod = nil - -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;]" - .."list[current_player;craftpreview;7,2;1,1;]" - .."listring[current_player;main]" - .."listring[current_player;craft]", - textures = {}, - default_skin = "character", - last_damage_types = {}, -} - -if minetest.get_modpath("mcl_skins") then - skin_mod = "mcl_skins" -elseif minetest.get_modpath("skins") then - skin_mod = "skins" -elseif minetest.get_modpath("simple_skins") then - skin_mod = "simple_skins" -elseif minetest.get_modpath("u_skins") then - skin_mod = "u_skins" -elseif minetest.get_modpath("wardrobe") then - skin_mod = "wardrobe" -end - -function armor.on_armor_use(itemstack, user, pointed_thing) - if not user or user:is_player() == false then - return itemstack - end - - -- Call on_rightclick if the pointed node defines it - if pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end - end - end - - local name, player_inv, armor_inv = armor:get_valid_player(user, "[on_armor_use]") - if not name then - return itemstack - end - - local def = itemstack:get_definition() - local slot - if def.groups and def.groups.armor_head then - slot = 2 - elseif def.groups and def.groups.armor_torso then - slot = 3 - elseif def.groups and def.groups.armor_legs then - slot = 4 - elseif def.groups and def.groups.armor_feet then - slot = 5 - end - - if slot then - local itemstack_single = ItemStack(itemstack) - itemstack_single:set_count(1) - local itemstack_slot = armor_inv:get_stack("armor", slot) - if itemstack_slot:is_empty() then - armor_inv:set_stack("armor", slot, itemstack_single) - player_inv:set_stack("armor", slot, itemstack_single) - armor:set_player_armor(user) - armor:update_inventory(user) - armor:play_equip_sound(itemstack_single, user) - itemstack:take_item() - elseif itemstack:get_count() <= 1 and not mcl_enchanting.has_enchantment(itemstack_slot, "curse_of_binding") then - armor_inv:set_stack("armor", slot, itemstack_single) - player_inv:set_stack("armor", slot, itemstack_single) - armor:set_player_armor(user) - armor:update_inventory(user) - armor:play_equip_sound(itemstack_single, user) - itemstack = ItemStack(itemstack_slot) - end - end - - return itemstack -end - -armor.def = { - count = 0, -} - -armor.update_player_visuals = function(self, player) - if not player then - return - end - - local wielditem = player:get_wielded_item() - local def = wielditem:get_definition() - if def and def._mcl_toollike_wield then - player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) - elseif string.find(wielditem:get_name(), "mcl_bows:bow") then - player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) - else - player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) - end - - local name = player:get_player_name() - if self.textures[name] then - mcl_player.player_set_textures(player, { - self.textures[name].skin, - self.textures[name].armor, - self.textures[name].wielditem, - }) - end -end - -armor.set_player_armor = function(self, player) - local name, player_inv = armor:get_valid_player(player, "[set_player_armor]") - if not name then - return - end - local armor_texture = "blank.png" - local armor_level = 0 - local mcl_armor_points = 0 - local items = 0 - local elements = {} - local textures = {} - local physics_o = {speed=1,gravity=1,jump=1} - local material = {type=nil, count=1} - local preview - for _,v in ipairs(self.elements) do - elements[v] = false - end - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - local item = stack:get_name() - if minetest.registered_aliases[item] then - item = minetest.registered_aliases[item] - end - if stack:get_count() == 1 then - local def = stack:get_definition() - for k, v in pairs(elements) do - if v == false then - local level = def.groups["armor_"..k] - if level then - local texture = def.texture or item:gsub("%:", "_") - local enchanted_addition = (mcl_enchanting.is_enchanted(item) and mcl_enchanting.overlay or "") - table.insert(textures, "("..texture..".png"..enchanted_addition..")") - preview = "(player.png^[opacity:0^"..texture.."_preview.png"..enchanted_addition..")"..(preview and "^"..preview or "") - armor_level = armor_level + level - items = items + 1 - mcl_armor_points = mcl_armor_points + (def.groups["mcl_armor_points"] or 0) - for kk,vv in ipairs(self.physics) do - local o_value = def.groups["physics_"..vv] - if o_value then - physics_o[vv] = physics_o[vv] + o_value - end - end - local mat = string.match(item, "%:.+_(.+)$") - if material.type then - if material.type == mat then - material.count = material.count + 1 - end - else - material.type = mat - end - elements[k] = true - end - end - end - end - end - preview = (armor:get_preview(name) or "character_preview.png")..(preview and "^"..preview or "") - if minetest.get_modpath("shields") then - armor_level = armor_level * 0.9 - end - if material.type and material.count == #self.elements then - armor_level = armor_level * 1.1 - end - if #textures > 0 then - armor_texture = table.concat(textures, "^") - end - local armor_groups = player:get_armor_groups() - armor_groups.fleshy = 100 - armor_groups.level = nil - if armor_level > 0 then - armor_groups.level = math.floor(armor_level / 20) - armor_groups.fleshy = 100 - armor_level - end - player:set_armor_groups(armor_groups) - -- Physics override intentionally removed because of possible conflicts - self.textures[name].armor = armor_texture - self.textures[name].preview = preview - self.def[name].count = items - self.def[name].level = armor_level - self.def[name].heal = mcl_armor_points - self.def[name].jump = physics_o.jump - self.def[name].speed = physics_o.speed - self.def[name].gravity = physics_o.gravity - self:update_player_visuals(player) -end - -armor.update_armor = function(self, player) - -- Legacy support: Called when armor levels are changed - -- Other mods can hook on to this function, see hud mod for example -end - -armor.get_armor_points = function(self, player) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_armor_points]") - if not name then - return nil - end - local pts = 0 - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local p = minetest.get_item_group(stack:get_name(), "mcl_armor_points") - if p then - pts = pts + p - end - end - end - return pts -end - --- Returns a change factor for a mob's view_range for the given player --- or nil, if there's no change. Certain armors (like mob heads) can --- affect the view range of mobs. -armor.get_mob_view_range_factor = function(self, player, mob) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[get_mob_view_range_factor]") - if not name then - return - end - local factor - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - if stack:get_count() > 0 then - local def = stack:get_definition() - if def._mcl_armor_mob_range_mob == mob then - if not factor then - factor = def._mcl_armor_mob_range_factor - elseif factor == 0 then - return 0 - else - factor = factor * def._mcl_armor_mob_range_factor - end - end - end - end - return factor -end - -armor.get_player_skin = function(self, name) - local skin = nil - if skin_mod == "mcl_skins" then - skin = mcl_skins.skins[name] - elseif skin_mod == "skins" or skin_mod == "simple_skins" then - skin = skins.skins[name] - elseif skin_mod == "u_skins" then - skin = u_skins.u_skins[name] - elseif skin_mod == "wardrobe" then - skin = string.gsub(wardrobe.playerSkins[name], "%.png$","") - end - return skin or armor.default_skin -end - -armor.get_preview = function(self, name) - if skin_mod == "skins" then - return armor:get_player_skin(name).."_preview.png" - end -end - -armor.get_armor_formspec = function(self, name) - if not armor.textures[name] then - minetest.log("error", "mcl_armor: Player texture["..name.."] is nil [get_armor_formspec]") - return "" - end - if not armor.def[name] then - minetest.log("error", "mcl_armor: Armor def["..name.."] is nil [get_armor_formspec]") - return "" - end - local formspec = armor.formspec.."list[detached:"..name.."_armor;armor;0,1;2,3;]" - formspec = formspec:gsub("armor_preview", armor.textures[name].preview) - formspec = formspec:gsub("armor_level", armor.def[name].level) - formspec = formspec:gsub("mcl_armor_points", armor.def[name].heal) - return formspec -end - -armor.update_inventory = function(self, player) -end - -armor.get_valid_player = function(self, player, msg) - msg = msg or "" - if not player then - minetest.log("error", "mcl_armor: Player reference is nil "..msg) - return - end - local name = player:get_player_name() - if not name then - minetest.log("error", "mcl_armor: Player name is nil "..msg) - return - end - local pos = player:get_pos() - local player_inv = player:get_inventory() - local armor_inv = minetest.get_inventory({type="detached", name=name.."_armor"}) - if not pos then - minetest.log("error", "mcl_armor: Player position is nil "..msg) - return - elseif not player_inv then - minetest.log("error", "mcl_armor: Player inventory is nil "..msg) - return - elseif not armor_inv then - minetest.log("error", "mcl_armor: Detached armor inventory is nil "..msg) - return - end - return name, player_inv, armor_inv, pos -end - -armor.play_equip_sound = function(self, stack, player, pos, unequip) - local def = stack:get_definition() - local estr = "equip" - if unequip then - estr = "unequip" - end - local snd = def.sounds and def.sounds["_mcl_armor_"..estr] - if not snd then - -- Fallback sound - snd = { name = "mcl_armor_"..estr.."_generic" } - end - if snd then - local dist = 8 - if pos then - dist = 16 - end - minetest.sound_play(snd, {object=player, pos=pos, gain=0.5, max_hear_distance=dist}, true) - end -end - --- Register Player Model - -mcl_player.player_register_model("mcl_armor_character.b3d", { - animation_speed = 30, - textures = { - armor.default_skin..".png", - "blank.png", - "blank.png", - }, - animations = { - stand = {x=0, y=79}, - lay = {x=162, y=166}, - walk = {x=168, y=187}, - mine = {x=189, y=198}, - walk_mine = {x=200, y=219}, - sit = {x=81, y=160}, - sneak_stand = {x=222, y=302}, - sneak_mine = {x=346, y=365}, - sneak_walk = {x=304, y=323}, - sneak_walk_mine = {x=325, y=344}, - swim_walk = {x=368, y=387}, - swim_walk_mine = {x=389, y=408}, - swim_stand = {x=434, y=434}, - swim_mine = {x=411, y=430}, - run_walk = {x=440, y=459}, - run_walk_mine = {x=461, y=480}, - sit_mount = {x=484, y=484}, - die = {x=498, y=498}, - fly = {x=502, y=581}, - }, -}) - -mcl_player.player_register_model("mcl_armor_character_female.b3d", { - animation_speed = 30, - textures = { - armor.default_skin..".png", - "blank.png", - "blank.png", - }, - animations = { - stand = {x=0, y=79}, - lay = {x=162, y=166}, - walk = {x=168, y=187}, - mine = {x=189, y=198}, - walk_mine = {x=200, y=219}, - sit = {x=81, y=160}, - sneak_stand = {x=222, y=302}, - sneak_mine = {x=346, y=365}, - sneak_walk = {x=304, y=323}, - sneak_walk_mine = {x=325, y=344}, - swim_walk = {x=368, y=387}, - swim_walk_mine = {x=389, y=408}, - swim_stand = {x=434, y=434}, - swim_mine = {x=411, y=430}, - run_walk = {x=440, y=459}, - run_walk_mine = {x=461, y=480}, - sit_mount = {x=484, y=484}, - die = {x=498, y=498}, - fly = {x=502, y=581}, - }, -}) - --- Register Callbacks - -minetest.register_on_player_receive_fields(function(player, formname, fields) - local name = armor:get_valid_player(player, "[on_player_receive_fields]") - if not name then - return - end - if fields.armor then - return - end - for field, _ in pairs(fields) do - if string.find(field, "skins_set") then - minetest.after(0, function(name) - local player = minetest.get_player_by_name(name) - if not player then - return - end - local skin = armor:get_player_skin(name) - armor.textures[name].skin = skin..".png" - armor:set_player_armor(player) - end, player:get_player_name()) - end - end -end) - -minetest.register_on_joinplayer(function(player) - mcl_player.player_set_model(player, "mcl_armor_character.b3d") - local name = player:get_player_name() - local player_inv = player:get_inventory() - local armor_inv = minetest.create_detached_inventory(name.."_armor", { - on_put = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, stack) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player) - end, - on_take = function(inv, listname, index, stack, player) - player:get_inventory():set_stack(listname, index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player, nil, true) - end, - on_move = function(inv, from_list, from_index, to_list, to_index, count, player) - local plaver_inv = player:get_inventory() - local stack = inv:get_stack(to_list, to_index) - player_inv:set_stack(to_list, to_index, stack) - player_inv:set_stack(from_list, from_index, nil) - armor:set_player_armor(player) - armor:update_inventory(player) - armor:play_equip_sound(stack, player) - end, - allow_put = function(inv, listname, index, stack, player) - local iname = stack:get_name() - local g - local groupcheck - if index == 2 then - g = minetest.get_item_group(iname, "armor_head") - elseif index == 3 then - g = minetest.get_item_group(iname, "armor_torso") - elseif index == 4 then - g = minetest.get_item_group(iname, "armor_legs") - elseif index == 5 then - g = minetest.get_item_group(iname, "armor_feet") - end - -- Minor FIXME: If player attempts to place stack into occupied slot, this is rejected. - -- It would be better if 1 item is placed in exchanged for the item in the slot. - if g ~= 0 and g ~= nil and (inv:get_stack(listname, index):is_empty() or (inv:get_stack(listname, index):get_name() ~= stack:get_name()) and stack:get_count() <= 1) then - return 1 - else - return 0 - end - end, - allow_take = function(inv, listname, index, stack, player) - if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.settings:get_bool("creative") then - return 0 - end - return stack:get_count() - end, - allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) - return 0 - end, - }, name) - armor_inv:set_size("armor", 6) - player_inv:set_size("armor", 6) - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - armor_inv:set_stack("armor", i, stack) - end - armor.def[name] = { - count = 0, - level = 0, - heal = 0, - jump = 1, - speed = 1, - gravity = 1, - } - armor.textures[name] = { - skin = armor.default_skin..".png", - armor = "blank.png", - wielditem = "blank.png", - preview = armor.default_skin.."_preview.png", - } - if skin_mod == "mcl_skins" then - local skin = mcl_skins.skins[name] - if skin then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "skins" then - local skin = skins.skins[name] - if skin and skins.get_type(skin) == skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "simple_skins" then - local skin = skins.skins[name] - if skin then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "u_skins" then - local skin = u_skins.u_skins[name] - if skin and u_skins.get_type(skin) == u_skins.type.MODEL then - armor.textures[name].skin = skin..".png" - end - elseif skin_mod == "wardrobe" then - local skin = wardrobe.playerSkins[name] - if skin then - armor.textures[name].skin = skin - end - end - if minetest.get_modpath("player_textures") then - local filename = minetest.get_modpath("player_textures").."/textures/player_"..name - local f = io.open(filename..".png") - if f then - f:close() - armor.textures[name].skin = "player_"..name..".png" - end - end - for i=1, ARMOR_INIT_TIMES do - minetest.after(ARMOR_INIT_DELAY * i, function(name) - local player = minetest.get_player_by_name(name) - if not player then - return - end - armor:set_player_armor(player) - end, player:get_player_name()) - end -end) - -minetest.register_on_player_hpchange(function(player, hp_change, reason) - local name, player_inv, armor_inv = armor:get_valid_player(player, "[on_hpchange]") - 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), - if reason.type == "set_hp" then - return hp_change - end - - local regular_reduction = reason.type ~= "drown" and reason.type ~= "fall" and reason.other ~= "harming" and reason.other ~= "poison" - - local heal_max = 0 - local items = 0 - local armor_damage = math.max(1, math.floor(math.abs(hp_change)/4)) - - local total_points = 0 - local total_toughness = 0 - local epf = 0 - local thorns_damage = 0 - local thorns_damage_regular = 0 - for i=1, 6 do - local stack = player_inv:get_stack("armor", i) - 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) - - armor.def[name].count = items - armor:update_armor(player) - end - return hp_change -end, true) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua new file mode 100644 index 000000000..9dce824ea --- /dev/null +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -0,0 +1,103 @@ +function mcl_armor.damage_modifier(obj, hp_change, reason) + if hp_change > 0 then + return hp_change + end + + local damage = -hp_change + local flags = reason.flags + + if flags.bypasses_armor and flags.bypasses_magic then + return hp_change + end + + local uses = math.max(1, math.floor(damage / 4)) + + local points = 0 + local toughness = 0 + local enchantment_protection_factor = 0 + + local thorns_damage_regular = 0 + local thorns_damage_irregular = 0 + local thorns_pieces = {} + + local inv = mcl_util.get_inventory(obj) + + if inv then + for name, element in pairs(mcl_armor.elements) do + local itemstack = inventory:get_stack("armor", element.index) + if not stack:is_empty() then + local itemname = stack:get_name() + local enchantments = mcl_enchanting.get_enchantments(itemstack) + + if not flags.bypasses_armor then + points = points + minetest.get_item_group(itemname, "mcl_armor_points") + toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") + + mcl_util.use_item_durability(itemstack, uses) + inventory:set_stack("armor", element.index, itemstack) + end + + if not flags.bypasses_magic then + local function add_enchantments(tbl) + if tbl then + for _, enchantment in pairs(tbl) do + local level = enchantments[enchantment.id] + + if level > 0 then + enchantment_protection_factor = enchantment_protection_factor + level * enchantment.factor + end + end + end + end + + add_enchantments(mcl_armor.protection_enchantments.wildcard) + add_enchantments(mcl_armor.protection_enchantments.types[reason.type]) + + for flag, value in pairs(flags) do + if value then + add_enchantments(mcl_armor.protection_enchantments.flags[flag]) + end + end + end + + if reason.source and enchantments.thorns > 0 then + local do_irregular_damage = enchantments.thorns > 10 + + if do_irregular_damage or thorns_damage_regular < 4 and math.random() < enchantments.thorns * 0.15 then + if do_irregular_damage then + thorns_damage_irregular = thorns_damage_irregular + throrns_level - 10 + else + thorns_damage_regular = math.min(4, thorns_damage_regular + math.random(4)) + end + end + + table.insert(thorns_pieces, {index = element.index, itemstack = itemstack}) + end + 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, enchantment_protection_factor) / 25) + + local thorns_damage = thorns_damage_regular + thorns_damage_irregular + + if thorns_damage > 0 and reason.source ~= obj then + mcl_util.deal_damage(reason.source, {type = "thorns", direct = obj, source = reason.source}) + + local thorns_item = thorns_pieces[math.random(#thorns_pieces)] + mcl_util.use_item_durability(thorns_item.itemstack, 2) + inventory:set_stack("armor", thorns_item.index, thorns_item.itemstack) + end + + mcl_armor.update(obj) + + return -math.floor(damage + 0.5) +end + +mcl_damage.register_modifier(function(player, hp_change, _, reason) + return mcl_armor.damage_modifier(player, hp_change, reason) +end) diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index bce597b7f..cc8fb2d32 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -1,405 +1,67 @@ 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") - --- 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:elytra", { - description = S("Elytra"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_elytra.png", - groups = {armor_torso=1, mcl_armor_points=0, mcl_armor_uses=10, enchantability=0}, - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_leather", { - description = S("Leather Cap"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_leather.png", - groups = {armor_head=1, mcl_armor_points=1, mcl_armor_uses=56, enchantability=15}, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_iron", { - description = S("Iron Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_iron.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_gold", { - description = S("Golden Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_gold.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=78, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_diamond",{ - description = S("Diamond Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_diamond.png", - groups = {armor_head=1, mcl_armor_points=3, mcl_armor_uses=364, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:helmet_chain", { - description = S("Chain Helmet"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_helmet_chain.png", - groups = {armor_head=1, mcl_armor_points=2, mcl_armor_uses=166, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Regisiter Torso Armor - -minetest.register_tool("mcl_armor:chestplate_leather", { - description = S("Leather Tunic"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_leather.png", - groups = {armor_torso=1, mcl_armor_points=3, mcl_armor_uses=81, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_iron", { - description = S("Iron Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_iron.png", - groups = {armor_torso=1, mcl_armor_points=6, mcl_armor_uses=241, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_gold", { - description = S("Golden Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_gold.png", - groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=113, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_diamond",{ - description = S("Diamond Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_diamond.png", - groups = {armor_torso=1, mcl_armor_points=8, mcl_armor_uses=529, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:chestplate_chain", { - description = S("Chain Chestplate"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_chestplate_chain.png", - groups = {armor_torso=1, mcl_armor_points=5, mcl_armor_uses=241, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Regisiter Leg Armor - -minetest.register_tool("mcl_armor:leggings_leather", { - description = S("Leather Pants"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_leather.png", - groups = {armor_legs=1, mcl_armor_points=2, mcl_armor_uses=76, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_iron", { - description = S("Iron Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_iron.png", - groups = {armor_legs=1, mcl_armor_points=5, mcl_armor_uses=226, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_gold", { - description = S("Golden Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_gold.png", - groups = {armor_legs=1, mcl_armor_points=3, mcl_armor_uses=106, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_diamond",{ - description = S("Diamond Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_diamond.png", - groups = {armor_legs=1, mcl_armor_points=6, mcl_armor_uses=496, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:leggings_chain", { - description = S("Chain Leggings"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_leggings_chain.png", - groups = {armor_legs=1, mcl_armor_points=4, mcl_armor_uses=226, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) --- Regisiter Boots - -minetest.register_tool("mcl_armor:boots_leather", { - description = S("Leather Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_leather.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=66, enchantability=15 }, - _repair_material = "mcl_mobitems:leather", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_leather", - _mcl_armor_unequip = "mcl_armor_unequip_leather", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_iron", { - description = S("Iron Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_iron.png", - groups = {armor_feet=1, mcl_armor_points=2, mcl_armor_uses=196, enchantability=9 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_gold", { - description = S("Golden Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_gold.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=92, enchantability=25 }, - _repair_material = "mcl_core:gold_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_iron", - _mcl_armor_unequip = "mcl_armor_unequip_iron", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_diamond",{ - description = S("Diamond Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_diamond.png", - groups = {armor_feet=1, mcl_armor_points=3, mcl_armor_uses=430, mcl_armor_toughness=2, enchantability=10 }, - _repair_material = "mcl_core:diamond", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_diamond", - _mcl_armor_unequip = "mcl_armor_unequip_diamond", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - -minetest.register_tool("mcl_armor:boots_chain", { - description = S("Chain Boots"), - _doc_items_longdesc = longdesc, - _doc_items_usagehelp = usage, - inventory_image = "mcl_armor_inv_boots_chain.png", - groups = {armor_feet=1, mcl_armor_points=1, mcl_armor_uses=196, enchantability=12 }, - _repair_material = "mcl_core:iron_ingot", - sounds = { - _mcl_armor_equip = "mcl_armor_equip_chainmail", - _mcl_armor_unequip = "mcl_armor_unequip_chainmail", - }, - on_place = armor.on_armor_use, - on_secondary_use = armor.on_armor_use, -}) - --- Register Craft Recipies - -local craft_ingreds = { - leather = { "mcl_mobitems:leather" }, - iron = { "mcl_core:iron_ingot", "mcl_core:iron_nugget" }, - gold = { "mcl_core:gold_ingot", "mcl_core:gold_nugget" }, - diamond = { "mcl_core:diamond" }, - chain = { nil, "mcl_core:iron_nugget"} , +mcl_armor = { + longdesc = S("This is a piece of equippable armor which reduces the amount of damage you receive."), + usage = S("To equip it, put it on the corresponding armor slot in your inventory menu."), + elements = { + head = { + name = "helmet", + description = "Helmet", + durability = 0.6857, + index = 2, + craft = function(m) + return { + { m, m, m}, + { m, "", m}, + {"", "", ""}, + } + end, + }, + torso = { + name = "chestplate", + description = "Chestplate", + durability = 1.0, + index = 3, + craft = function(m) + return { + { m, "", m}, + { m, m, m}, + { m, m, m}, + } + end, + }, + legs = { + name = "leggings", + description = "Leggings", + durability = 0.9375, + index = 4, + craft = function(m) + return { + { m, m, m}, + { m, "", m}, + { m, "", m}, + } + end, + }, + feet = { + name = "boots", + description = "Boots", + durability = 0.8125, + index = 5, + craft = function(m) + return { + { m, "", m}, + { m, "", m}, + } + end, + } + } } -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 +local modpath = minetest.get_modpath("mcl_armor") + +dofile(modpath .. "/api.lua") +dofile(modpath .. "/player.lua") +dofile(modpath .. "/damage.lua") +dofile(modpath .. "/register.lua") +dofile(modpath .. "/alias.lua") diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua new file mode 100644 index 000000000..a00429040 --- /dev/null +++ b/mods/ITEMS/mcl_armor/player.lua @@ -0,0 +1,143 @@ +mcl_player.player_register_model("mcl_armor_character.b3d", { + animation_speed = 30, + textures = { + "character.png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + sneak_stand = {x=222, y=302}, + sneak_mine = {x=346, y=365}, + sneak_walk = {x=304, y=323}, + sneak_walk_mine = {x=325, y=344}, + swim_walk = {x=368, y=387}, + swim_walk_mine = {x=389, y=408}, + swim_stand = {x=434, y=434}, + swim_mine = {x=411, y=430}, + run_walk = {x=440, y=459}, + run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, + die = {x=498, y=498}, + fly = {x=502, y=581}, + }, +}) + +mcl_player.player_register_model("mcl_armor_character_female.b3d", { + animation_speed = 30, + textures = { + "character.png", + "blank.png", + "blank.png", + }, + animations = { + stand = {x=0, y=79}, + lay = {x=162, y=166}, + walk = {x=168, y=187}, + mine = {x=189, y=198}, + walk_mine = {x=200, y=219}, + sit = {x=81, y=160}, + sneak_stand = {x=222, y=302}, + sneak_mine = {x=346, y=365}, + sneak_walk = {x=304, y=323}, + sneak_walk_mine = {x=325, y=344}, + swim_walk = {x=368, y=387}, + swim_walk_mine = {x=389, y=408}, + swim_stand = {x=434, y=434}, + swim_mine = {x=411, y=430}, + run_walk = {x=440, y=459}, + run_walk_mine = {x=461, y=480}, + sit_mount = {x=484, y=484}, + die = {x=498, y=498}, + fly = {x=502, y=581}, + }, +}) + +function mcl_armor.update_player(player, info) + mcl_player.player_set_armor(player, info.texture, info.preview) + + player:get_meta():set_int("mcl_armor:armor_point", info.points) +end + +local function is_armor_action(inventory_info) + return inventory_info.from_list == "armor" or inventory_info.to_list == "armor" or inventory_info.listname == "armor" +end + +local function limit_put(player, inventory, index, stack, count) + local def = stack:get_definition() + + if not def then + return 0 + end + + local element = def._mcl_armor_element + + if not element then + return 0 + end + + if mcl_armor.elements[element].index ~= index then + return 0 + end + + local old_stack = inventory:get_stack("armor", index) + + if old_stack:is_empty() or old_stack:get_name() ~= stack:get_name() and count <= 1 then + return count + else + return 0 + end +end + +local function limit_take(player, inventory, index, stack, count) + if mcl_enchanting.has_enchantment(stack, "curse_of_binding") and not minetest.is_creative_enabled(player:get_player_name()) then + return 0 + end + + return count +end + +minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info) + if not is_armor_action(inventory_info) then + return + end + + if action == "put" then + return limit_put(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count()) + elseif action == "take" then + return limit_take(player, inventory, inventory_info.index, inventory_info.stack, inventory_info.stack:get_count()) + else + if inventory_info.from_list ~= "armor" then + return limit_put(player, inventory, inventory_info.to_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count) + elseif inventory_info.to_list ~= "armor" then + return limit_take(player, inventory, inventory_info.from_index, inventory:get_stack(inventory_info.from_list, inventory_info.from_index), inventory_info.count) + else + return 0 + end + end +end) + +-- ToDo: Call unequip callbacks & play uneqip sound +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + if is_armor_action(inventory_info) then + mcl_armor.update(player) + end +end) + +minetest.register_on_joinplayer(function(player) + mcl_player.player_set_model(player, "mcl_armor_character.b3d") + player:get_inventory():set_size("armor", 5) + + minetest.after(1, function() + if player:is_player() then + mcl_armor.update(player) + end + end) +end) + + diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua new file mode 100644 index 000000000..91410f659 --- /dev/null +++ b/mods/ITEMS/mcl_armor/register.lua @@ -0,0 +1,204 @@ +local S = minetest.get_translator("mcl_armor") + +mcl_armor.register_set({ + name = "leather", + description = "Leather", + descriptions = { + head = "Cap", + torso = "Tunic", + legs = "Pants", + }, + durability = 80, + enchantability = 15, + points = { + head = 1, + torso = 3, + legs = 2, + feet = 1, + }, + craft_material = "mcl_mobitems:leather", +}) + +mcl_armor.register_set({ + name = "gold", + description = "Golden", + durability = 112, + enchantability = 25, + points = { + head = 2, + torso = 5, + legs = 3, + feet = 1, + }, + craft_material = "mcl_core:gold_ingot", + cook_material = "mcl_core:gold_nugget", + sound_equip = "mcl_armor_equip_iron", + sound_unequip = "mcl_armor_unequip_iron", +}) + +mcl_armor.register_set({ + name = "chain", + description = "Chain", + durability = 240, + enchantability = 12, + points = { + head = 2, + torso = 5, + legs = 4, + feet = 1, + }, + repair_material = "mcl_core:iron_ingot", + cook_material = "mcl_core:iron_nugget", +}) + +mcl_armor.register_set({ + name = "iron", + description = "Iron", + durability = 240, + enchantability = 9, + points = { + head = 2, + torso = 6, + legs = 5, + feet = 2, + }, + craft_material = "mcl_core:iron_ingot", + cook_material = "mcl_core:iron_nugget", +}) + +mcl_armor.register_set({ + name = "diamond", + description = "Diamond", + durability = 528, + enchantability = 10, + points = { + head = 3, + torso = 8, + legs = 6, + feet = 3, + }, + toughness = 2, + craft_material = "mcl_core:diamond", +}) + +mcl_armor.register_protection_enchantment({ + id = "projectile_protection", + name = S("Projectile Protection"), + description = S("Reduces projectile damage."), + power_range_table = {{1, 16}, {11, 26}, {21, 36}, {31, 46}, {41, 56}}, + incompatible = {blast_protection = true, fire_protection = true, protection = true}, + factor = 2, + damage_flag = "is_projectile", +}) + +mcl_armor.register_protection_enchantment({ + id = "blast_protection", + name = S("Blast Protection"), + description = S("Reduces explosion damage and knockback."), + power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}}, + weight = 2, + incompatible = {fire_protection = true, protection = true, projectile_protection = true}, + factor = 2, + damage_flag = "is_explosion", +}) + +mcl_armor.register_protection_enchantment({ + id = "fire_protection", + name = S("Fire Protection"), + description = S("Reduces fire damage."), + power_range_table = {{5, 13}, {13, 21}, {21, 29}, {29, 37}}, + incompatible = {blast_protection = true, protection = true, projectile_protection = true}, + factor = 2, + damage_flag = "is_fire", +}) + +mcl_armor.register_protection_enchantment({ + id = "protection", + name = S("Protection"), + description = S("Reduces most types of damage by 4% for each level."), + power_range_table = {{1, 12}, {12, 23}, {23, 34}, {34, 45}}, + incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true}, + factor = 1, +}) + +mcl_armor.register_protection_enchantment({ + id = "feather_falling", + name = S("Feather Falling"), + description = S("Reduces fall damage."), + power_range_table = {{5, 11}, {11, 17}, {17, 23}, {23, 29}}, + factor = 3, + primary = {combat_armor_feet = true}, + damage_type = "fall", +}) + +-- requires engine change +--[[mcl_enchanting.enchantments.aqua_affinity = { + name = S("Aqua Affinity"), + max_level = 1, + primary = {armor_head = true}, + secondary = {}, + disallow = {non_combat_armor = true}, + incompatible = {}, + weight = 2, + description = S("Increases underwater mining speed."), + curse = false, + on_enchant = function() end, + requires_tool = false, + treasure = false, + power_range_table = {{1, 41}}, + 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_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.thorns = { + name = S("Thorns"), + max_level = 3, + primary = {combat_armor_chestplate = true}, + secondary = {combat_armor = true}, + 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, +} + +-- Elytra + +minetest.register_tool("mcl_armor:elytra", { + description = S("Elytra"), + _doc_items_longdesc = mcl_armor.longdesc, + _doc_items_usagehelp = mcl_armor.usage, + inventory_image = "mcl_armor_inv_elytra.png", + groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10}, + sounds = { + _mcl_armor_equip = "mcl_armor_equip_leather", + _mcl_armor_unequip = "mcl_armor_unequip_leather", + }, + on_place = mcl_armor.equip_on_use, + on_secondary_use = mcl_armor.equip_on_use, + _mcl_armor_element = "torso", +}) diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index c451b6de1..5dc427231 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -150,7 +150,7 @@ minetest.register_node("mcl_armor_stand:armor_stand", { single_item:set_count(1) if inv:is_empty(list) then inv:add_item(list, single_item) - armor:play_equip_sound(single_item, nil, pos) + mcl_armor.play_equip_sound(single_item, nil, pos) update_entity(pos) itemstack:take_item() return itemstack @@ -175,7 +175,7 @@ minetest.register_node("mcl_armor_stand:armor_stand", { taken = true end if taken then - armor:play_equip_sound(stand_armor, nil, pos, true) + mcl_armor.play_equip_sound(stand_armor, nil, pos, true) stand_armor:take_item() inv:set_stack("armor_" .. elements[e], 1, stand_armor) end diff --git a/mods/ITEMS/mcl_bows/arrow.lua b/mods/ITEMS/mcl_bows/arrow.lua index cddae0869..6e68c7c31 100644 --- a/mods/ITEMS/mcl_bows/arrow.lua +++ b/mods/ITEMS/mcl_bows/arrow.lua @@ -69,6 +69,7 @@ local ARROW_ENTITY={ _stuckrechecktimer=nil,-- An additional timer for periodically re-checking the stuck status of an arrow _stuckin=nil, --Position of node in which arow is stuck. _shooter=nil, -- ObjectRef of player or mob who shot it + _is_arrow = true, _viscosity=0, -- Viscosity of node the arrow is currently in _deflection_cooloff=0, -- Cooloff timer after an arrow deflection, to prevent many deflections in quick succession @@ -254,9 +255,6 @@ ARROW_ENTITY.on_step = function(self, dtime) -- Punch target object but avoid hurting enderman. 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 if self._in_player == false then damage_particles(self.object:get_pos(), self._is_critical) end diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 45912384e..2257fcc5e 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -59,6 +59,7 @@ mcl_bows.shoot_arrow = function(arrow_item, pos, dir, yaw, shooter, power, damag obj:set_yaw(yaw-math.pi/2) local le = obj:get_luaentity() le._shooter = shooter + le._source_object = shooter le._damage = damage le._is_critical = is_critical le._startpos = pos diff --git a/mods/ITEMS/mcl_core/nodes_liquid.lua b/mods/ITEMS/mcl_core/nodes_liquid.lua index 4696a629a..c49b685eb 100644 --- a/mods/ITEMS/mcl_core/nodes_liquid.lua +++ b/mods/ITEMS/mcl_core/nodes_liquid.lua @@ -203,7 +203,7 @@ S("• When lava is directly above water, the water turns into stone."), _mcl_node_death_message = lava_death_messages, post_effect_color = {a=245, r=208, g=73, b=10}, stack_max = 64, - groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15}, + groups = { lava=3, lava_source=1, liquid=2, destroys_items=1, not_in_creative_inventory=1, dig_by_piston=1, set_on_fire=15, fire_damage=1}, _mcl_blast_resistance = 100, -- Hardness intentionally set to infinite instead of 100 (Minecraft value) to avoid problems in creative mode _mcl_hardness = -1, diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index ca936c319..34cc5cf98 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -10,25 +10,6 @@ local function increase_damage(damage_group, factor) end end --- requires engine change ---[[mcl_enchanting.enchantments.aqua_affinity = { - name = S("Aqua Affinity"), - max_level = 1, - primary = {armor_head = true}, - secondary = {}, - disallow = {non_combat_armor = true}, - incompatible = {}, - weight = 2, - description = S("Increases underwater mining speed."), - curse = false, - on_enchant = function() end, - requires_tool = false, - treasure = false, - power_range_table = {{1, 41}}, - inv_combat_tab = true, - inv_tool_tab = false, -}]]-- - -- implemented via on_enchant and additions in mobs_mc; Slowness IV part unimplemented mcl_enchanting.enchantments.bane_of_arthropods = { name = S("Bane of Arthropods"), @@ -48,25 +29,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 +48,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, -} - -- implemented in mcl_death_drop mcl_enchanting.enchantments.curse_of_vanishing = { name = S("Curse of Vanishing"), @@ -164,24 +107,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"), @@ -213,25 +138,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, @@ -530,44 +436,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"), @@ -739,25 +607,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"), diff --git a/mods/ITEMS/mcl_enchanting/engine.lua b/mods/ITEMS/mcl_enchanting/engine.lua index ea69d1868..db164637b 100644 --- a/mods/ITEMS/mcl_enchanting/engine.lua +++ b/mods/ITEMS/mcl_enchanting/engine.lua @@ -266,7 +266,8 @@ function mcl_enchanting.initialize() new_def.groups.not_in_creative_inventory = 1 new_def.groups.not_in_craft_guide = 1 new_def.groups.enchanted = 1 - new_def.texture = itemdef.texture or itemname:gsub("%:", "_") + new_def._mcl_armor_texture = new_def._mcl_armor_texture and new_def._mcl_armor_texture .. mcl_enchanting.overlay + new_def._mcl_armor_preview = new_def._mcl_armor_preview and new_def._mcl_armor_preview .. mcl_enchanting.overlay new_def._mcl_enchanting_enchanted_tool = new_name new_def.after_use = get_after_use_callback(itemdef) local register_list = register_item_list diff --git a/mods/ITEMS/mcl_farming/pumpkin.lua b/mods/ITEMS/mcl_farming/pumpkin.lua index 72b4e5412..8d234d586 100644 --- a/mods/ITEMS/mcl_farming/pumpkin.lua +++ b/mods/ITEMS/mcl_farming/pumpkin.lua @@ -111,12 +111,16 @@ pumpkin_face_base_def.description = S("Pumpkin") pumpkin_face_base_def._doc_items_longdesc = S("A pumpkin can be worn as a helmet. Pumpkins grow from pumpkin stems, which in turn grow from pumpkin seeds.") pumpkin_face_base_def._doc_items_usagehelp = nil pumpkin_face_base_def.tiles = {"farming_pumpkin_top.png", "farming_pumpkin_top.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_side.png", "farming_pumpkin_face.png"} +pumpkin_face_base_def.groups.armor=1 +pumpkin_face_base_def.groups.non_combat_armor=1 pumpkin_face_base_def.groups.armor_head=1 +pumpkin_face_base_def.groups.non_combat_armor_head=1 pumpkin_face_base_def._mcl_armor_mob_range_factor = 0 pumpkin_face_base_def._mcl_armor_mob_range_mob = "mobs_mc:enderman" +pumpkin_face_base_def._mcl_armor_entry = "head" pumpkin_face_base_def.groups.non_combat_armor=1 if minetest.get_modpath("mcl_armor") then - pumpkin_face_base_def.on_secondary_use = armor.on_armor_use + pumpkin_face_base_def.on_secondary_use = mcl_armor.equip_on_use end -- Register stem growth diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 95d76c45d..96c6195aa 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -203,7 +203,7 @@ minetest.register_node("mcl_fire:fire", { sunlight_propagates = true, damage_per_second = 1, _mcl_node_death_message = fire_death_messages, - groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8}, + groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8, fire_damage=1}, floodable = true, on_flood = function(pos, oldnode, newnode) if get_item_group(newnode.name, "water") ~= 0 then @@ -334,7 +334,7 @@ minetest.register_node("mcl_fire:eternal_fire", { sunlight_propagates = true, damage_per_second = 1, _mcl_node_death_message = fire_death_messages, - groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8}, + groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8, fire_damage=1}, floodable = true, on_flood = function(pos, oldnode, newnode) if get_item_group(newnode.name, "water") ~= 0 then diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index 2000c7070..27d6ef793 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -5,7 +5,7 @@ local mod_screwdriver = minetest.get_modpath("screwdriver") local equip_armor if minetest.get_modpath("mcl_armor") then - equip_armor = armor.on_armor_use + equip_armor = mcl_armor.equip_on_use end -- Heads system diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 996637aa7..2d66611f3 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -603,21 +603,18 @@ function mcl_potions.make_invisible(player, toggle) return end - if minetest.get_modpath("mcl_armor") and player:is_player() then - armor.textures[playername].skin = skin_file - armor:update_player_visuals(player) - elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then + if player:is_player() then + mcl_player.player_set_skin(player, "mobs_mc_empty.png") + elseif not player:is_player() then player:set_properties({visual_size = {x = 0, y = 0}}) end player:set_nametag_attributes({color = {a = 0}}) elseif EF.invisible[player] then -- show player - if minetest.get_modpath("mcl_armor") and player:is_player() then - skin_file = mcl_skins.skins[playername] .. ".png" - armor.textures[playername].skin = skin_file - armor:update_player_visuals(player) - elseif not player:is_player() and minetest.get_modpath("mcl_armor") or not player:is_player() and not minetest.get_modpath("mcl_armor") then + if player:is_player() then + mcl_skins.update_player_skin(player) + elseif not player:is_player() then player:set_properties({visual_size = EF.invisible[player].old_size}) end player:set_nametag_attributes({color = {r = 255, g = 255, b = 255, a = 255}}) diff --git a/mods/ITEMS/mcl_torches/api.lua b/mods/ITEMS/mcl_torches/api.lua index ced566bbd..74cde8d51 100644 --- a/mods/ITEMS/mcl_torches/api.lua +++ b/mods/ITEMS/mcl_torches/api.lua @@ -277,7 +277,7 @@ minetest.register_lbm({ nodenames = {"group:torch_particles"}, run_at_every_load = true, action = function(pos, node) - local torch_group = minetest.get_node_group(node.name, "torch") + local torch_group = minetest.get_item_group(node.name, "torch") if torch_group == 1 then spawn_flames_floor(pos) elseif torch_group == 2 then diff --git a/mods/ITEMS/screwdriver/init.lua b/mods/ITEMS/screwdriver/init.lua index e6aedf19c..62a217f8e 100644 --- a/mods/ITEMS/screwdriver/init.lua +++ b/mods/ITEMS/screwdriver/init.lua @@ -157,7 +157,7 @@ screwdriver.handler = function(itemstack, user, pointed_thing, mode, uses) if should_rotate and new_param2 ~= node.param2 then node.param2 = new_param2 minetest.swap_node(pos, node) - + minetest.check_for_falling(pos) if ndef.after_rotate then ndef.after_rotate(vector.new(pos)) diff --git a/mods/PLAYER/mcl_death_drop/init.lua b/mods/PLAYER/mcl_death_drop/init.lua index 7c54334a9..49be58679 100644 --- a/mods/PLAYER/mcl_death_drop/init.lua +++ b/mods/PLAYER/mcl_death_drop/init.lua @@ -11,7 +11,6 @@ end mcl_death_drop.register_dropped_list("PLAYER", "main", true) mcl_death_drop.register_dropped_list("PLAYER", "craft", true) mcl_death_drop.register_dropped_list("PLAYER", "armor", true) -mcl_death_drop.register_dropped_list(function(player) return select(3, armor:get_valid_player(player)) end , "armor", false) minetest.register_on_dieplayer(function(player) local keep = minetest.settings:get_bool("mcl_keepInventory", false) @@ -50,7 +49,6 @@ minetest.register_on_dieplayer(function(player) inv:set_list(listname, {}) end end - armor:set_player_armor(player) - armor:update_inventory(player) + mcl_armor.update(player) end end) diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 210e2d19f..7ff40809b 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -88,22 +88,41 @@ function mcl_player.player_set_model(player, model_name) player_model[name] = model_name end -function mcl_player.player_set_textures(player, textures, preview) - local name = player:get_player_name() - player_textures[name] = textures - player:set_properties({textures = textures,}) - if preview then - player:get_meta():set_string("mcl_player:preview", preview) - end +local function set_texture(player, index, texture) + local textures = player_textures[player:get_player_name()] + textures[index] = texture + player:set_properties({textures = textures}) +end + +local function set_preview(player, field, preview) + player:get_meta():set_string("mcl_player:" .. field .. "_preview", preview) +end + +function mcl_player.player_set_skin(player, texture, preview) + set_texture(player, 1, texture) + set_preview(player, "skin", preview) +end + +function mcl_player.player_set_armor(player, texture, preview) + set_texture(player, 2, texture) + set_preview(player, "armor", preview) +end + +function mcl_player.player_set_wielditem(player, texture) + set_texture(player, 3, texture) end function mcl_player.player_get_preview(player) - local preview = player:get_meta():get_string("mcl_player:preview") - if preview == nil or preview == "" then - return "player.png" - else - return preview + local preview = player:get_meta():get_string("mcl_player:skin_preview") + if preview == "" then + preview = "player.png" end + local armor_preview = player:get_meta():set_string("mcl_player:armor_preview") + if armor_preview ~= "" then + preview = preview .. "^" .. armor_preview + end + return preview + end function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) @@ -129,8 +148,10 @@ end -- Update appearance when the player joins minetest.register_on_joinplayer(function(player) - mcl_player.player_attached[player:get_player_name()] = false + local name = player:get_player_name() + mcl_player.player_attached[name] = false mcl_player.player_set_model(player, "character.b3d") + player_textures[name] = {"blank.png", "blank.png", "blank.png"} --player:set_local_animation({x=0, y=79}, {x=168, y=187}, {x=189, y=198}, {x=200, y=219}, 30) player:set_fov(86.1) -- see >>> end) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 5ba73cd60..4177a9d55 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -182,6 +182,8 @@ minetest.register_globalstep(function(dtime) local wielded = player:get_wielded_item() local player_velocity = player:get_velocity() or player:get_player_velocity() + local wielded_def = wielded:get_definition() + -- controls head bone local pitch = - degrees(player:get_look_vertical()) local yaw = degrees(player:get_look_horizontal()) @@ -196,7 +198,7 @@ minetest.register_globalstep(function(dtime) if minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}) then node_stand_return = minetest.get_node_or_nil({x=player:get_pos().x, y=player:get_pos().y - 0.5, z=player:get_pos().z}).name else - minetest.log("action", "somehow player got of loaded areas") + -- minetest.log("action", "somehow player got of loaded areas") end if player:get_inventory():get_stack("armor", 3):get_name() == "mcl_armor:elytra" and player_velocity.y < -6 and elytra[player] ~= true and is_sprinting(name) then @@ -224,6 +226,14 @@ minetest.register_globalstep(function(dtime) playerphysics.remove_physics_factor(player, "gravity", "mcl_playerplus:elytra") end + if wielded_def and wielded_def._mcl_toollike_wield then + player:set_bone_position("Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) + elseif string.find(wielded:get_name(), "mcl_bows:bow") then + player:set_bone_position("Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) + else + player:set_bone_position("Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) + end + -- controls right and left arms pitch when shooting a bow if string.find(wielded:get_name(), "mcl_bows:bow") and controls.RMB and not controls.LMB and not controls.up and not controls.down and not controls.left and not controls.right then player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35)) diff --git a/mods/PLAYER/mcl_skins/init.lua b/mods/PLAYER/mcl_skins/init.lua index 5956aab7c..fccc00365 100644 --- a/mods/PLAYER/mcl_skins/init.lua +++ b/mods/PLAYER/mcl_skins/init.lua @@ -7,7 +7,6 @@ mcl_skins = { } local S = minetest.get_translator("mcl_skins") -local has_mcl_armor = minetest.get_modpath("mcl_armor") local has_mcl_inventory = minetest.get_modpath("mcl_inventory") -- load skin list and metadata @@ -115,10 +114,6 @@ mcl_skins.set_player_skin = function(player, skin_id) mcl_skins.previews[playername] = preview player:get_meta():set_string("mcl_skins:skin_id", tostring(skin_id)) mcl_skins.update_player_skin(player) - if has_mcl_armor then - armor.textures[playername].skin = skin_file - armor:update_player_visuals(player) - end if has_mcl_inventory then mcl_inventory.update_inventory_formspec(player) end @@ -134,7 +129,7 @@ mcl_skins.update_player_skin = function(player) return end local playername = player:get_player_name() - mcl_player.player_set_textures(player, { mcl_skins.skins[playername] .. ".png" }, mcl_skins.previews[playername] .. ".png" ) + mcl_player.player_set_skin(player, mcl_skins.skins[playername] .. ".png", mcl_skins.previews[playername] .. ".png") end -- load player skin on join diff --git a/mods/PLAYER/mcl_skins/mod.conf b/mods/PLAYER/mcl_skins/mod.conf index 6ccbe98f1..657d3cc0e 100644 --- a/mods/PLAYER/mcl_skins/mod.conf +++ b/mods/PLAYER/mcl_skins/mod.conf @@ -2,4 +2,4 @@ name = mcl_skins author = TenPlus1 description = Mod that allows players to set their individual skins. depends = mcl_player -optional_depends = mcl_inventory, intllib, mcl_armor +optional_depends = mcl_inventory, intllib diff --git a/mods/PLAYER/wieldview/LICENSE.txt b/mods/PLAYER/mcl_wieldview/LICENSE.txt similarity index 100% rename from mods/PLAYER/wieldview/LICENSE.txt rename to mods/PLAYER/mcl_wieldview/LICENSE.txt diff --git a/mods/PLAYER/wieldview/README.txt b/mods/PLAYER/mcl_wieldview/README.txt similarity index 100% rename from mods/PLAYER/wieldview/README.txt rename to mods/PLAYER/mcl_wieldview/README.txt diff --git a/mods/PLAYER/mcl_wieldview/init.lua b/mods/PLAYER/mcl_wieldview/init.lua new file mode 100644 index 000000000..7be3b83dc --- /dev/null +++ b/mods/PLAYER/mcl_wieldview/init.lua @@ -0,0 +1,122 @@ +mcl_wieldview = { + players = {} +} + +function mcl_wieldview.get_item_texture(itemname) + if itemname == "" then + return + end + + local def = minetest.registered_items[itemname] + if not def then + return + end + + local inv_image = def.inventory_image + if inv_image == "" then + return + end + + local texture = inv_image + + local transform = minetest.get_item_group(itemname, "wieldview_transform") + if transform then + -- This actually works with groups ratings because transform1, transform2, etc. + -- have meaning and transform0 is used for identidy, so it can be ignored + texture = texture .. "^[transform" .. transform + end + + return texture +end + +function mcl_wieldview.update_wielded_item(player) + if not player then + return + end + local name = player:get_player_name() + local itemstack = player:get_wielded_item() + local itemname = itemstack:get_name() + + local def = mcl_wieldview.players[name] + + if def.item == itemname then + return + end + + def.item = itemname + def.texture = mcl_wieldview.get_item_texture(itemname) or "blank.png" + + mcl_player.player_set_wielditem(player, def.texture) +end + +minetest.register_on_joinplayer(function(player) + local name = player:get_player_name() + mcl_wieldview.players[name] = {item = "", texture = "blank.png"} + + minetest.after(0, function() + if not player:is_player() then + return + end + + mcl_wieldview.update_wielded_item(player) + + local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode") + itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) + itementity:get_luaentity().wielder = name + end) +end) + +minetest.register_on_leaveplayer(function(player) + local name = player:get_player_name() + mcl_wieldview.players[name] = nil +end) + +minetest.register_globalstep(function() + for _, player in pairs(minetest.get_connected_players()) do + mcl_wieldview.update_wielded_item(player) + end +end) + +minetest.register_entity("mcl_wieldview:wieldnode", { + initial_properties = { + hp_max = 1, + visual = "wielditem", + physical = false, + textures = {""}, + automatic_rotate = 1.5, + is_visible = true, + pointable = false, + collide_with_objects = false, + static_save = false, + collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, + visual_size = {x = 0.21, y = 0.21}, + }, + + itemstring = "", + + on_step = function(self) + local player = minetest.get_player_by_name(self.wielder) + if player then + local wielded = player:get_wielded_item() + local itemstring = wielded:get_name() + + if self.itemstring ~= itemstring then + local def = minetest.registered_items[itemstring] + self.object:set_properties({glow = def and def.light_source or 0}) + + -- wield item as cubic + if mcl_wieldview.players[self.wielder].texture == "blank.png" then + self.object:set_properties({textures = {itemstring}}) + -- wield item as flat + else + self.object:set_properties({textures = {""}}) + end + + self.itemstring = itemstring + end + else + self.object:remove() + end + end, +}) diff --git a/mods/PLAYER/wieldview/mod.conf b/mods/PLAYER/mcl_wieldview/mod.conf similarity index 66% rename from mods/PLAYER/wieldview/mod.conf rename to mods/PLAYER/mcl_wieldview/mod.conf index 4cd2a6935..4b3097876 100644 --- a/mods/PLAYER/wieldview/mod.conf +++ b/mods/PLAYER/mcl_wieldview/mod.conf @@ -1,5 +1,4 @@ -name = wieldview +name = mcl_wieldview author = stujones11 description = Makes hand wielded items visible to other players. -depends = mcl_armor - +depends = mcl_player diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua deleted file mode 100644 index 7a349f2f3..000000000 --- a/mods/PLAYER/wieldview/init.lua +++ /dev/null @@ -1,132 +0,0 @@ -local time = 0 -local update_time = tonumber(minetest.settings:get("wieldview_update_time")) -if not update_time then - update_time = 2 - minetest.settings:set("wieldview_update_time", tostring(update_time)) -end -local node_tiles = minetest.settings:get_bool("wieldview_node_tiles") -if not node_tiles then - node_tiles = false - minetest.settings:set("wieldview_node_tiles", "false") -end - -wieldview = { - wielded_item = {}, - transform = {}, -} - -dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua") - -wieldview.get_item_texture = function(self, item) - local texture = "blank.png" - if item ~= "" then - if minetest.registered_items[item] then - if minetest.registered_items[item].inventory_image ~= "" then - texture = minetest.registered_items[item].inventory_image - elseif node_tiles == true and minetest.registered_items[item].tiles - and type(minetest.registered_items[item].tiles[1]) == "string" - and minetest.registered_items[item].tiles[1] ~= "" then - texture = minetest.inventorycube(minetest.registered_items[item].tiles[1]) - end - end - -- Get item image transformation, first from group, then from transform.lua - local transform = minetest.get_item_group(item, "wieldview_transform") - if transform == 0 then - transform = wieldview.transform[item] - end - if transform then - -- This actually works with groups ratings because transform1, transform2, etc. - -- have meaning and transform0 is used for identidy, so it can be ignored - texture = texture.."^[transform"..tostring(transform) - end - end - return texture -end - -wieldview.update_wielded_item = function(self, player) - if not player then - return - end - local name = player:get_player_name() - local stack = player:get_wielded_item() - local item = stack:get_name() - if not item then - return - end - if self.wielded_item[name] then - if self.wielded_item[name] == item then - return - end - if not armor.textures[name] then - return - end - armor.textures[name].wielditem = self:get_item_texture(item) - armor:update_player_visuals(player) - end - self.wielded_item[name] = item -end - -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - wieldview.wielded_item[name] = "" - minetest.after(0, function(player) - -- if the player left :is_player() will return nil - if not player:is_player() then - return - end - wieldview:update_wielded_item(player) - local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode") - itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) - itementity:get_luaentity().wielder = name - end, player) -end) - -minetest.register_globalstep(function() - for _,player in pairs(minetest.get_connected_players()) do - wieldview:update_wielded_item(player) - end -end) - -minetest.register_entity("wieldview:wieldnode", { - initial_properties = { - hp_max = 1, - visual = "wielditem", - physical = false, - textures = {""}, - automatic_rotate = 1.5, - is_visible = true, - pointable = false, - collide_with_objects = false, - static_save = false, - collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, - selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, - visual_size = {x = 0.21, y = 0.21}, - }, - - itemstring = "", - - on_step = function(self) - local player = minetest.get_player_by_name(self.wielder) - if player then - local wielded = player:get_wielded_item() - local itemstring = wielded:get_name() - - if self.itemstring ~= itemstring then - local def = minetest.registered_items[itemstring] - self.object:set_properties({glow = def and def.light_source or 0}) - - -- wield item as cubic - if armor.textures[self.wielder].wielditem == "blank.png" then - self.object:set_properties({textures = {itemstring}}) - -- wield item as flat - else - self.object:set_properties({textures = {""}}) - end - - self.itemstring = itemstring - end - else - self.object:remove() - end - end, -}) diff --git a/mods/PLAYER/wieldview/transform.lua b/mods/PLAYER/wieldview/transform.lua deleted file mode 100644 index a19956796..000000000 --- a/mods/PLAYER/wieldview/transform.lua +++ /dev/null @@ -1,10 +0,0 @@ --- Wielded Item Transformations - http://dev.minetest.net/texture - -wieldview.transform = { - ["screwdriver:screwdriver"]="R90", - ["screwdriver:screwdriver1"]="R90", - ["screwdriver:screwdriver2"]="R90", - ["screwdriver:screwdriver3"]="R90", - ["screwdriver:screwdriver4"]="R90", -} - From e74838136d3c42a7768864d301943a02268cc202 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 16:27:21 +0200 Subject: [PATCH 02/43] Use cactus damage type --- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index fa735a5cd..2001ddbd2 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -456,7 +456,7 @@ minetest.register_globalstep(function(dtime) if dist < 1.1 or dist_feet < 1.1 then if player:get_hp() > 0 then mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name)) - player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" }) + player:set_hp(player:get_hp() - 1, { _mcl_type = "cactus" }) end end end From 875bb3db8419d63fbd7295e8147e4d3588d2909a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 17:20:51 +0200 Subject: [PATCH 03/43] Use fire-like damage types properly --- mods/CORE/mcl_damage/init.lua | 7 +++++-- mods/ENTITIES/mcl_burning/api.lua | 2 +- mods/ITEMS/mcl_fire/init.lua | 4 ++-- mods/ITEMS/mcl_nether/init.lua | 2 +- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index bd640be43..927ce6771 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -70,10 +70,13 @@ function mcl_damage.get_mcl_damage_reason(mt_reason) mcl_reason.type = "player" end end - elseif mt_reason.type == "node_damage" then - if minetest.get_item_group(reason.node or "", "fire_damage") > 0 then + elseif mt_reason.type == "node_damage" and mt_reason.node then + if minetest.get_item_group(mt_reason.node, "fire") > 0 then mcl_reason.type = "in_fire" end + if minetest.get_item_group(mt_reason.node, "lava") > 0 then + mcl_reason.type = "lava" + end end for key, value in pairs(mt_reason) do diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 98f315ef9..4f4452a57 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -106,7 +106,7 @@ function mcl_burning.damage(obj) end if do_damage then - mcl_util.deal_damage(obj, 1, {type = "in_fire"}) + mcl_util.deal_damage(obj, 1, {type = "on_fire"}) end end diff --git a/mods/ITEMS/mcl_fire/init.lua b/mods/ITEMS/mcl_fire/init.lua index 96c6195aa..95d76c45d 100644 --- a/mods/ITEMS/mcl_fire/init.lua +++ b/mods/ITEMS/mcl_fire/init.lua @@ -203,7 +203,7 @@ minetest.register_node("mcl_fire:fire", { sunlight_propagates = true, damage_per_second = 1, _mcl_node_death_message = fire_death_messages, - groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8, fire_damage=1}, + groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston=1, destroys_items=1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) if get_item_group(newnode.name, "water") ~= 0 then @@ -334,7 +334,7 @@ minetest.register_node("mcl_fire:eternal_fire", { sunlight_propagates = true, damage_per_second = 1, _mcl_node_death_message = fire_death_messages, - groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8, fire_damage=1}, + groups = {fire = 1, dig_immediate = 3, not_in_creative_inventory = 1, dig_by_piston = 1, destroys_items = 1, set_on_fire=8}, floodable = true, on_flood = function(pos, oldnode, newnode) if get_item_group(newnode.name, "water") ~= 0 then diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index 467054767..b6285ceb4 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -114,7 +114,7 @@ minetest.register_node("mcl_nether:magma", { if mod_death_messages then mcl_death_messages.player_damage(player, S("@1 stood too long on a magma block.", player:get_player_name())) end - player:set_hp(player:get_hp() - 1, { type = "punch", from = "mod" }) + mcl_util.deal_damage(player, 1, {type = "hot_floor"}) end end, _mcl_blast_resistance = 0.5, diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 2001ddbd2..64dbb1088 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -456,7 +456,7 @@ minetest.register_globalstep(function(dtime) if dist < 1.1 or dist_feet < 1.1 then if player:get_hp() > 0 then mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name)) - player:set_hp(player:get_hp() - 1, { _mcl_type = "cactus" }) + mcl_util.deal_damage(player, 1, {type = "cactus"}) end end end From 49e7def70aabd18be9d156e538dbd074abf2f9c9 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 18:40:41 +0200 Subject: [PATCH 04/43] Implement lightning_bolt damage reason --- mods/ENVIRONMENT/lightning/init.lua | 74 +++++++++++++---------------- 1 file changed, 34 insertions(+), 40 deletions(-) diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 345f733d5..64a304dbe 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -139,48 +139,42 @@ lightning.strike = function(pos) for o=1, #objs do local obj = objs[o] local lua = obj:get_luaentity() - if obj:is_player() then - -- Player damage - if has_mcl_death_msg then + -- pig → zombie pigman (no damage) + if lua and lua.name == "mobs_mc:pig" then + local rot = obj:get_yaw() + obj:remove() + obj = add_entity(pos2, "mobs_mc:pigman") + obj:set_yaw(rot) + -- mooshroom: toggle color red/brown (no damage) + elseif lua and lua.name == "mobs_mc:mooshroom" then + if lua.base_texture[1] == "mobs_mc_mooshroom.png" then + lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } + else + lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } + end + obj:set_properties({textures = lua.base_texture}) + -- villager → witch (no damage) + elseif lua and lua.name == "mobs_mc:villager" then + -- Witches are incomplete, this code is unused + -- TODO: Enable this code when witches are working. + --[[ + local rot = obj:get_yaw() + obj:remove() + obj = minetest.add_entity(pos2, "mobs_mc:witch") + obj:set_yaw(rot) + ]] + -- charged creeper + elseif lua and lua.name == "mobs_mc:creeper" then + local rot = obj:get_yaw() + obj:remove() + obj = add_entity(pos2, "mobs_mc:creeper_charged") + obj:set_yaw(rot) + -- Other objects: Just damage + else + if obj:is_player() and has_mcl_death_msg then mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name())) end - obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) - -- Mobs - elseif lua and lua._cmi_is_mob then - -- pig → zombie pigman (no damage) - if lua.name == "mobs_mc:pig" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:pigman") - obj:set_yaw(rot) - -- mooshroom: toggle color red/brown (no damage) - elseif lua.name == "mobs_mc:mooshroom" then - if lua.base_texture[1] == "mobs_mc_mooshroom.png" then - lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } - else - lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" } - end - obj:set_properties({textures = lua.base_texture}) - -- villager → witch (no damage) - elseif lua.name == "mobs_mc:villager" then - -- Witches are incomplete, this code is unused - -- TODO: Enable this code when witches are working. - --[[ - local rot = obj:get_yaw() - obj:remove() - obj = minetest.add_entity(pos2, "mobs_mc:witch") - obj:set_yaw(rot) - ]] - -- charged creeper - elseif lua.name == "mobs_mc:creeper" then - local rot = obj:get_yaw() - obj:remove() - obj = add_entity(pos2, "mobs_mc:creeper_charged") - obj:set_yaw(rot) - -- Other mobs: Just damage - else - obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) - end + mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"}) end end From 5d9bb7cacd485f0cd9335758dacdd6196971e8bf Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 19:06:11 +0200 Subject: [PATCH 05/43] Fix armor not actually protecting lol --- mods/CORE/mcl_damage/init.lua | 5 +++-- mods/ITEMS/mcl_armor/damage.lua | 14 +++++--------- mods/ITEMS/mcl_armor/player.lua | 4 +++- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 927ce6771..83c6d83af 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -39,7 +39,7 @@ function minetest.register_on_player_hpchange(func, modifier) end function mcl_damage.register_modifier(func, priority) - table.insert(mcl_damage, {func = func, priority = priority or 0}) + table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0}) end function mcl_damage.get_mcl_damage_reason(mt_reason) @@ -86,8 +86,9 @@ function mcl_damage.get_mcl_damage_reason(mt_reason) end mcl_reason.source = mcl_reason.source or mcl_reason.direct - mcl_reason.flags = mcl_damage.types[mcl_reason.type] + + return mcl_reason end function mcl_damage.register_type(name, def) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index 9dce824ea..35ae0eb30 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -24,9 +24,9 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) if inv then for name, element in pairs(mcl_armor.elements) do - local itemstack = inventory:get_stack("armor", element.index) - if not stack:is_empty() then - local itemname = stack:get_name() + local itemstack = inv:get_stack("armor", element.index) + if not itemstack:is_empty() then + local itemname = itemstack:get_name() local enchantments = mcl_enchanting.get_enchantments(itemstack) if not flags.bypasses_armor then @@ -34,7 +34,7 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) toughness = toughness + minetest.get_item_group(itemname, "mcl_armor_toughness") mcl_util.use_item_durability(itemstack, uses) - inventory:set_stack("armor", element.index, itemstack) + inv:set_stack("armor", element.index, itemstack) end if not flags.bypasses_magic then @@ -90,14 +90,10 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) local thorns_item = thorns_pieces[math.random(#thorns_pieces)] mcl_util.use_item_durability(thorns_item.itemstack, 2) - inventory:set_stack("armor", thorns_item.index, thorns_item.itemstack) + inv:set_stack("armor", thorns_item.index, thorns_item.itemstack) end mcl_armor.update(obj) return -math.floor(damage + 0.5) end - -mcl_damage.register_modifier(function(player, hp_change, _, reason) - return mcl_armor.damage_modifier(player, hp_change, reason) -end) diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index a00429040..776d22dd6 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -140,4 +140,6 @@ minetest.register_on_joinplayer(function(player) end) end) - +mcl_damage.register_modifier(function(player, hp_change, _, reason) + return mcl_armor.damage_modifier(player, hp_change, reason) +end) From 4e37cc114c8201c22c0b99ed05608e35d5fb6c46 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 19:06:30 +0200 Subject: [PATCH 06/43] Implement out_of_world damage type --- mods/ENVIRONMENT/mcl_void_damage/init.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mods/ENVIRONMENT/mcl_void_damage/init.lua b/mods/ENVIRONMENT/mcl_void_damage/init.lua index ee40ed702..ac39d10ba 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/init.lua +++ b/mods/ENVIRONMENT/mcl_void_damage/init.lua @@ -40,7 +40,6 @@ minetest.register_on_mods_loaded(function() end self._void_timer = 0 - local pos = obj:get_pos() local void, void_deadly = is_in_void(pos) if void_deadly then local ent = obj:get_luaentity() @@ -81,7 +80,7 @@ minetest.register_globalstep(function(dtime) -- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds) if player:get_hp() > 0 then death_msg(player, S("@1 fell into the endless void.", player:get_player_name())) - player:set_hp(player:get_hp() - VOID_DAMAGE) + mcl_util.deal_damage(player, VOID_DAMAGE, {type = "out_of_world"}) end end end From a3af1cdf6e8752c081af5c8f519ef0249fbe4090 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 19:07:58 +0200 Subject: [PATCH 07/43] Implement in_wall damage type --- mods/PLAYER/mcl_playerplus/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 64dbb1088..443e2d741 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -440,7 +440,7 @@ minetest.register_globalstep(function(dtime) and (not check_player_privs(name, {noclip = true})) then if player:get_hp() > 0 then mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name)) - player:set_hp(player:get_hp() - 1) + mcl_util.deal_damage(player, 1, {type = "in_wall"}) end end From 9c75cd1a791be54cad10c42e9471d586b1684022 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 19:09:46 +0200 Subject: [PATCH 08/43] Implement starve damage --- mods/PLAYER/mcl_hunger/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index b640dfdc9..8bc2d9582 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -164,7 +164,7 @@ minetest.register_globalstep(function(dtime) if mod_death_messages then mcl_death_messages.player_damage(player, S("@1 starved to death.", name)) end - player:set_hp(hp-1) + mcl_util.deal_damage(player, 1, {type = "starve"}) end end end From ec6d68322a257606018c1210bf0c8f0d2971c07f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 20:08:08 +0200 Subject: [PATCH 09/43] Make hbarmor work --- mods/ITEMS/mcl_armor/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 776d22dd6..92494b88f 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -61,7 +61,7 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", { function mcl_armor.update_player(player, info) mcl_player.player_set_armor(player, info.texture, info.preview) - player:get_meta():set_int("mcl_armor:armor_point", info.points) + player:get_meta():set_int("mcl_armor:armor_points", info.points) end local function is_armor_action(inventory_info) From 727d7be6abfcc9dd663a7c49e14cc26f5d632a70 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 20:39:05 +0200 Subject: [PATCH 10/43] Call on_equip and on_unequip everytime needed --- mods/ITEMS/mcl_armor/api.lua | 23 +++++++++++++++++++---- mods/ITEMS/mcl_armor/player.lua | 13 +++++++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index 3f0641a54..a5d1ac0e5 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -18,6 +18,24 @@ function mcl_armor.play_equip_sound(stack, obj, pos, unequip) end end +function mcl_armor.on_equip(itemstack, obj) + local def = itemstack:get_definition() + mcl_armor.play_equip_sound(itemstack, obj) + if def._on_equip then + def._on_equip(obj, itemstack) + end + mcl_armor.update(obj) +end + +function mcl_armor.on_unequip(itemstack, obj) + local def = itemstack:get_definition() + mcl_armor.play_equip_sound(itemstack, obj, nil, true) + if def._on_unequip then + def._on_unequip(obj, itemstack) + end + mcl_armor.update(obj) +end + function mcl_armor.equip(itemstack, obj) local def = itemstack:get_definition() local element = mcl_armor.elements[def._mcl_armor_element or ""] @@ -27,10 +45,7 @@ function mcl_armor.equip(itemstack, obj) if inv:get_stack("armor", element.index):is_empty() then local equipping_item = itemstack:take_item() inv:set_stack("armor", element.index, equipping_item) - if def._on_equip then - def._on_equip(equipping_item) - end - mcl_armor.update(obj) + mcl_armor.on_equip(equipping_item, obj) end end diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 92494b88f..651f8f776 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -122,10 +122,19 @@ minetest.register_allow_player_inventory_action(function(player, action, invento end end) --- ToDo: Call unequip callbacks & play uneqip sound minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) if is_armor_action(inventory_info) then - mcl_armor.update(player) + if action == "put" then + mcl_armor.on_equip(inventory_info.stack, player) + elseif action == "take" then + mcl_armor.on_unequip(inventory_info.stack, player) + else + if inventory_info.to_list == "armor" then + mcl_armor.on_equip(inventory:get_stack(inventory_info.to_list, inventory_info.to_index), player) + elseif inventory_info.from_list == "armor" then + mcl_armor.on_unequip(inventory:get_stack(inventory_info.to_list, inventory_info.to_index), player) + end + end end end) From 8931ffb7d32564687418a2590f1406945a8e1dcb Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 14 Apr 2021 20:39:35 +0200 Subject: [PATCH 11/43] Fix crash with armor enchantments --- mods/ITEMS/mcl_armor/damage.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index 35ae0eb30..43d39869d 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -43,7 +43,7 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) for _, enchantment in pairs(tbl) do local level = enchantments[enchantment.id] - if level > 0 then + if level and level > 0 then enchantment_protection_factor = enchantment_protection_factor + level * enchantment.factor end end From 4d515e95c6bc5b6e30ed6a5d9ebcca0941731a9f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 12:58:40 +0200 Subject: [PATCH 12/43] Remove wieldview --- mods/PLAYER/wieldview/init.lua | 131 --------------------------------- 1 file changed, 131 deletions(-) delete mode 100644 mods/PLAYER/wieldview/init.lua diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua deleted file mode 100644 index 91b2cd721..000000000 --- a/mods/PLAYER/wieldview/init.lua +++ /dev/null @@ -1,131 +0,0 @@ -local update_time = tonumber(minetest.settings:get("wieldview_update_time")) -if not update_time then - update_time = 2 - minetest.settings:set("wieldview_update_time", tostring(update_time)) -end -local node_tiles = minetest.settings:get_bool("wieldview_node_tiles") -if not node_tiles then - node_tiles = false - minetest.settings:set("wieldview_node_tiles", "false") -end - -wieldview = { - wielded_item = {}, - transform = {}, -} - -dofile(minetest.get_modpath(minetest.get_current_modname()).."/transform.lua") - -wieldview.get_item_texture = function(self, item) - local texture = "blank.png" - if item ~= "" then - if minetest.registered_items[item] then - if minetest.registered_items[item].inventory_image ~= "" then - texture = minetest.registered_items[item].inventory_image - elseif node_tiles == true and minetest.registered_items[item].tiles - and type(minetest.registered_items[item].tiles[1]) == "string" - and minetest.registered_items[item].tiles[1] ~= "" then - texture = minetest.inventorycube(minetest.registered_items[item].tiles[1]) - end - end - -- Get item image transformation, first from group, then from transform.lua - local transform = minetest.get_item_group(item, "wieldview_transform") - if transform == 0 then - transform = wieldview.transform[item] - end - if transform then - -- This actually works with groups ratings because transform1, transform2, etc. - -- have meaning and transform0 is used for identidy, so it can be ignored - texture = texture.."^[transform"..tostring(transform) - end - end - return texture -end - -wieldview.update_wielded_item = function(self, player) - if not player then - return - end - local name = player:get_player_name() - local stack = player:get_wielded_item() - local item = stack:get_name() - if not item then - return - end - if self.wielded_item[name] then - if self.wielded_item[name] == item then - return - end - if not armor.textures[name] then - return - end - armor.textures[name].wielditem = self:get_item_texture(item) - armor:update_player_visuals(player) - end - self.wielded_item[name] = item -end - -minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - wieldview.wielded_item[name] = "" - minetest.after(0, function(target) - -- if the player left :is_player() will return nil - if not target:is_player() then - return - end - wieldview:update_wielded_item(target) - local itementity = minetest.add_entity(target:get_pos(), "wieldview:wieldnode") - itementity:set_attach(target, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) - itementity:get_luaentity().wielder = name - end, player) -end) - -minetest.register_globalstep(function() - for _,player in pairs(minetest.get_connected_players()) do - wieldview:update_wielded_item(player) - end -end) - -minetest.register_entity("wieldview:wieldnode", { - initial_properties = { - hp_max = 1, - visual = "wielditem", - physical = false, - textures = {""}, - automatic_rotate = 1.5, - is_visible = true, - pointable = false, - collide_with_objects = false, - static_save = false, - collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, - selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, - visual_size = {x = 0.21, y = 0.21}, - }, - - itemstring = "", - - on_step = function(self) - local player = minetest.get_player_by_name(self.wielder) - if player then - local wielded = player:get_wielded_item() - local itemstring = wielded:get_name() - - if self.itemstring ~= itemstring then - local def = minetest.registered_items[itemstring] - self.object:set_properties({glow = def and def.light_source or 0}) - - -- wield item as cubic - if armor.textures[self.wielder].wielditem == "blank.png" then - self.object:set_properties({textures = {itemstring}}) - -- wield item as flat - else - self.object:set_properties({textures = {""}}) - end - - self.itemstring = itemstring - end - else - self.object:remove() - end - end, -}) From d952423dda778bd675c1a3ffc00fb35136c5894f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 13:24:30 +0200 Subject: [PATCH 13/43] Improve wielditem performance and fix wielditems sometimes showing duplicate --- mods/PLAYER/mcl_wieldview/init.lua | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/mods/PLAYER/mcl_wieldview/init.lua b/mods/PLAYER/mcl_wieldview/init.lua index 7be3b83dc..fc9ebc074 100644 --- a/mods/PLAYER/mcl_wieldview/init.lua +++ b/mods/PLAYER/mcl_wieldview/init.lua @@ -33,11 +33,10 @@ function mcl_wieldview.update_wielded_item(player) if not player then return end - local name = player:get_player_name() local itemstack = player:get_wielded_item() local itemname = itemstack:get_name() - local def = mcl_wieldview.players[name] + local def = mcl_wieldview.players[player] if def.item == itemname then return @@ -50,8 +49,7 @@ function mcl_wieldview.update_wielded_item(player) end minetest.register_on_joinplayer(function(player) - local name = player:get_player_name() - mcl_wieldview.players[name] = {item = "", texture = "blank.png"} + mcl_wieldview.players[player] = {item = "", texture = "blank.png"} minetest.after(0, function() if not player:is_player() then @@ -62,13 +60,12 @@ minetest.register_on_joinplayer(function(player) local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode") itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45)) - itementity:get_luaentity().wielder = name + itementity:get_luaentity().wielder = player end) end) minetest.register_on_leaveplayer(function(player) - local name = player:get_player_name() - mcl_wieldview.players[name] = nil + mcl_wieldview.players[player] = nil end) minetest.register_globalstep(function() @@ -96,17 +93,16 @@ minetest.register_entity("mcl_wieldview:wieldnode", { itemstring = "", on_step = function(self) - local player = minetest.get_player_by_name(self.wielder) - if player then - local wielded = player:get_wielded_item() - local itemstring = wielded:get_name() + if self.wielder:is_player() then + local def = mcl_wieldview.players[self.wielder] + local itemstring = def.item if self.itemstring ~= itemstring then - local def = minetest.registered_items[itemstring] - self.object:set_properties({glow = def and def.light_source or 0}) + local itemdef = minetest.registered_items[itemstring] + self.object:set_properties({glow = itemdef and itemdef.light_source or 0}) -- wield item as cubic - if mcl_wieldview.players[self.wielder].texture == "blank.png" then + if def.texture == "blank.png" then self.object:set_properties({textures = {itemstring}}) -- wield item as flat else From c7c47c1ca76ef94f78e513414a842e949e607256 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 13:49:40 +0200 Subject: [PATCH 14/43] Increase mob_view_range_factor performance --- mods/ENTITIES/mcl_mobs/api.lua | 3 +- mods/ITEMS/mcl_armor/api.lua | 56 +++++++++------------------------ mods/ITEMS/mcl_armor/init.lua | 3 +- mods/ITEMS/mcl_armor/player.lua | 9 +++++- 4 files changed, 27 insertions(+), 44 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 87aff0d76..d5caee66f 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -177,7 +177,8 @@ local function object_in_range(self, object) local factor -- Apply view range reduction for special player armor if object:is_player() and mod_armor then - factor = mcl_armor.get_mob_view_range_factor(object, self.name) + local factors = mcl_armor.player_view_range_factors[object] + factor = factors and factors[self.name] end -- Distance check local dist diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index a5d1ac0e5..9f9384c6d 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -160,48 +160,8 @@ function mcl_armor.register_protection_enchantment(def) } end -function mcl_armor.get_armor_points(obj) - local points = 0 - local inv = mcl_util.get_inventory(obj) - if inv then - for i = 2, 5 do - local itemstack = inv:get_stack("armor", i) - if not itemstack:is_empty() then - points = points + minetest.get_item_group(itemstack:get_name(), "mcl_armor_points") - end - end - end - return points -end - --- Returns a change factor for a mob's view_range for the given object --- or nil, if there's no change. Certain armors (like mob heads) can --- affect the view range of mobs. -function mcl_armor.get_mob_view_range_factor(obj, mob) - local inv = mcl_util.get_inventory(obj) - local factor - if inv then - for i = 2, 5 do - local itemstack = inv:get_stack("armor", i) - if not itemstack:is_empty() then - local def = itemstack:get_definition() - if def._mcl_armor_mob_range_mob == mob then - if not factor then - factor = def._mcl_armor_mob_range_factor - elseif factor == 0 then - return 0 - else - factor = factor * def._mcl_armor_mob_range_factor - end - end - end - end - end - return factor -end - function mcl_armor.update(obj) - local info = {points = 0} + local info = {points = 0, view_range_factors = {}} local inv = mcl_util.get_inventory(obj) @@ -226,6 +186,20 @@ function mcl_armor.update(obj) end info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points") + + local mob_range_mob = def._mcl_armor_mob_range_mob + + if mob_range_mob then + local factor = info.view_range_factors[mob_range_mob] + + if factor then + if factor > 0 then + info.view_range_factors[mob_range_mob] = factor * def._mcl_armor_mob_range_factor + end + else + info.view_range_factors[mob_range_mob] = def._mcl_armor_mob_range_factor + end + end end end end diff --git a/mods/ITEMS/mcl_armor/init.lua b/mods/ITEMS/mcl_armor/init.lua index cc8fb2d32..0f7725010 100644 --- a/mods/ITEMS/mcl_armor/init.lua +++ b/mods/ITEMS/mcl_armor/init.lua @@ -55,7 +55,8 @@ mcl_armor = { } end, } - } + }, + player_view_range_factors = {}, } local modpath = minetest.get_modpath("mcl_armor") diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 651f8f776..50828fcea 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -61,7 +61,10 @@ mcl_player.player_register_model("mcl_armor_character_female.b3d", { function mcl_armor.update_player(player, info) mcl_player.player_set_armor(player, info.texture, info.preview) - player:get_meta():set_int("mcl_armor:armor_points", info.points) + local meta = player:get_meta() + meta:set_int("mcl_armor:armor_points", info.points) + + mcl_armor.player_view_range_factors[player] = view_range_factors end local function is_armor_action(inventory_info) @@ -149,6 +152,10 @@ minetest.register_on_joinplayer(function(player) end) end) +minetest.register_on_leaveplayer(function(player) + mcl_armor.player_view_range_factors[player] = nil +end) + mcl_damage.register_modifier(function(player, hp_change, _, reason) return mcl_armor.damage_modifier(player, hp_change, reason) end) From 6bbea11fb83370db2af459caf2bb57e130982efd Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 13:53:41 +0200 Subject: [PATCH 15/43] Fix crash with mcl_heads --- mods/ITEMS/mcl_heads/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index d6ae3dca9..cd8d71faa 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -90,7 +90,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) local wdir = minetest.dir_to_wallmounted(diff) local itemstring = itemstack:get_name() - --local fakestack = ItemStack(itemstack) + local fakestack = ItemStack(itemstack) local idef = fakestack:get_definition() local retval if wdir == 0 or wdir == 1 then From 6724a8d0ed493914c8f406fb8e6463a7609789b2 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 13:59:46 +0200 Subject: [PATCH 16/43] Fix crash in damage handler --- mods/ITEMS/mcl_armor/damage.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index 43d39869d..e6d13dfa7 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -60,7 +60,7 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) end end - if reason.source and enchantments.thorns > 0 then + if reason.source and enchantments.thorns and enchantments.thorns > 0 then local do_irregular_damage = enchantments.thorns > 10 if do_irregular_damage or thorns_damage_regular < 4 and math.random() < enchantments.thorns * 0.15 then From 8e37b51cac861b87db3dc52ea2143575bd306e1a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 14:07:47 +0200 Subject: [PATCH 17/43] Equip mob heads with rightclick --- mods/ITEMS/mcl_heads/init.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_heads/init.lua b/mods/ITEMS/mcl_heads/init.lua index cd8d71faa..ec6a5638e 100644 --- a/mods/ITEMS/mcl_heads/init.lua +++ b/mods/ITEMS/mcl_heads/init.lua @@ -42,7 +42,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, }, }, }, - groups = {handy=1, armor_head=1,non_combat_armor=1, head=1, deco_block=1, dig_by_piston=1 }, + groups = {handy = 1, armor = 1, armor_head = 1, non_combat_armor = 1, non_combat_armor_head = 1, head = 1, deco_block = 1, dig_by_piston = 1}, -- The head textures are based off the textures of an actual mob. tiles = { -- Note: bottom texture is overlaid over top texture to get rid of possible transparency. @@ -111,6 +111,7 @@ local function addhead(name, texture, desc, longdesc, rangemob, rangefactor) _mcl_armor_mob_range_mob = rangemob, _mcl_armor_mob_range_factor = rangefactor, + _mcl_armor_element = "head", _mcl_blast_resistance = 1, _mcl_hardness = 1, }) From bbd115fde011b258f17b201221bc0760175289af Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sat, 17 Apr 2021 18:39:38 +0200 Subject: [PATCH 18/43] Update armor stand --- mods/ITEMS/mcl_armor_stand/init.lua | 44 ++++++++--------------------- 1 file changed, 11 insertions(+), 33 deletions(-) diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index 5dc427231..9a5a6d050 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -21,8 +21,8 @@ local function get_stand_object(pos) return object end -local function update_entity(pos) - local node = minetest.get_node(pos) +local function update_entity(pos, node) + local node = node or minetest.get_node(pos) local object = get_stand_object(pos) if object then if not string.find(node.name, "mcl_armor_stand:") then @@ -33,31 +33,7 @@ local function update_entity(pos) object = minetest.add_entity(pos, "mcl_armor_stand:armor_entity") end if object then - local texture = "blank.png" - local textures = {} - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() local yaw = 0 - if inv then - for _, element in pairs(elements) do - local stack = inv:get_stack("armor_"..element, 1) - if stack:get_count() == 1 then - local item = stack:get_name() or "" - if minetest.registered_aliases[item] then - item = minetest.registered_aliases[item] - end - local def = stack:get_definition() or {} - local groups = def.groups or {} - if groups["armor_"..element] then - local texture = def.texture or item:gsub("%:", "_") - table.insert(textures, texture..".png") - end - end - end - end - if #textures > 0 then - texture = table.concat(textures, "^") - end if node.param2 then local rot = node.param2 % 4 if rot == 1 then @@ -69,7 +45,7 @@ local function update_entity(pos) end end object:set_yaw(yaw) - object:set_properties({textures={texture}}) + mcl_armor.update(object) end end @@ -257,13 +233,15 @@ minetest.register_entity("mcl_armor_stand:armor_entity", { textures = {"blank.png"}, pos = nil, timer = 0, - on_activate = function(self) - local pos = self.object:get_pos() + on_activate = function(self, staticdata) self.object:set_armor_groups({immortal=1}) - if pos then - self.pos = vector.round(pos) - update_entity(pos) - end + local pos = self.object:get_pos() + self.pos = vector.round(pos) + self.inventory = minetest.get_meta(pos):get_inventory() + update_entity(pos) + end, + update_armor = function(self, info) + self.object:set_properties({textures = {info.texture}}) end, on_step = function(self, dtime) if not self.pos then From 4f0bb444fed5548ea1c1bb308519c57706a2f5fb Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 16:03:23 +0200 Subject: [PATCH 19/43] Integrate armor stand --- mods/CORE/mcl_util/init.lua | 9 +- mods/ITEMS/mcl_armor/api.lua | 24 ++- mods/ITEMS/mcl_armor_stand/init.lua | 258 +++++++--------------------- 3 files changed, 85 insertions(+), 206 deletions(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 55f308602..49d1c82a1 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -422,10 +422,13 @@ end function mcl_util.call_on_rightclick(itemstack, player, pointed_thing) -- Call on_rightclick if the pointed node defines it if pointed_thing and pointed_thing.type == "node" then - local node = minetest.get_node(pointed_thing.under) + local pos = pointed_thing.under + local node = minetest.get_node(pos) if player and not player:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack + local nodedef = minetest.registered_nodes[node.name] + local on_rightclick = nodedef and nodedef.on_rightclick + if on_rightclick then + return on_rightclick(pos, node, player, itemstack, pointed_thing) or itemstack end end end diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index 9f9384c6d..c3a84f265 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -36,16 +36,30 @@ function mcl_armor.on_unequip(itemstack, obj) mcl_armor.update(obj) end -function mcl_armor.equip(itemstack, obj) +function mcl_armor.equip(itemstack, obj, swap) local def = itemstack:get_definition() + + if not def then + return itemstack + end + local element = mcl_armor.elements[def._mcl_armor_element or ""] local inv = mcl_util.get_inventory(obj) if element and inv then - if inv:get_stack("armor", element.index):is_empty() then - local equipping_item = itemstack:take_item() - inv:set_stack("armor", element.index, equipping_item) - mcl_armor.on_equip(equipping_item, obj) + local old_stack = inv:get_stack("armor", element.index) + local new_stack + + if swap then + new_stack = itemstack + itemstack = old_stack + else + new_stack = itemstack:take_item() + end + + if swap or old_stack:is_empty() then + inv:set_stack("armor", element.index, new_stack) + mcl_armor.on_equip(new_stack, obj) end end diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index 9a5a6d050..8bcb06134 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -1,60 +1,41 @@ local S = minetest.get_translator("mcl_armor_stand") -local elements = {"head", "torso", "legs", "feet"} - -local function get_stand_object(pos) - local object = nil - local objects = minetest.get_objects_inside_radius(pos, 0.5) or {} - for _, obj in pairs(objects) do - local ent = obj:get_luaentity() - if ent then - if ent.name == "mcl_armor_stand:armor_entity" then - -- Remove duplicates - if object then - obj:remove() - else - object = obj - end - end - end - end - return object +-- Spawn a stand entity +local function spawn_stand_entity(pos, node) + local luaentity = minetest.add_entity(pos, "mcl_armor_stand:armor_entity"):get_luaentity() + luaentity:update_rotation(node or minetest.get_node(pos)) + return luaentity end -local function update_entity(pos, node) - local node = node or minetest.get_node(pos) - local object = get_stand_object(pos) - if object then - if not string.find(node.name, "mcl_armor_stand:") then - object:remove() - return +-- Find a stand entity or spawn one +local function get_stand_entity(pos, node) + for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 0)) do + local luaentity = obj:get_luaentity() + if luaentity and luaentity.name == "mcl_armor_stand:armor_entity" then + return luaentity end - else - object = minetest.add_entity(pos, "mcl_armor_stand:armor_entity") end - if object then - local yaw = 0 - if node.param2 then - local rot = node.param2 % 4 - if rot == 1 then - yaw = 3 * math.pi / 2 - elseif rot == 2 then - yaw = math.pi - elseif rot == 3 then - yaw = math.pi / 2 - end + return spawn_stand_entity(pos, node) +end + +-- Migrate the old inventory format +local function migrate_inventory(inv) + inv:set_size("armor", 5) + local lists = inv:get_lists() + for name, element in pairs(mcl_armor.elements) do + local listname = "armor_" .. name + local list = lists[listname] + if list then + inv:set_stack("armor", element.index, list[1]) + inv:set_size(listname, 0) end - object:set_yaw(yaw) - mcl_armor.update(object) end end --- Drop all armor of the armor stand on the ground -local drop_armor = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - for _, element in pairs(elements) do - local stack = inv:get_stack("armor_"..element, 1) +-- Drop all armor on the ground when it got destroyed +local function drop_inventory(pos) + local inv = minetest.get_meta(pos):get_inventory() + for _, stack in pairs(inv:get_list("armor")) do if not stack:is_empty() then local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5} minetest.add_item(p, stack) @@ -87,136 +68,27 @@ minetest.register_node("mcl_armor_stand:armor_stand", { _mcl_hardness = 2, sounds = mcl_sounds.node_sound_wood_defaults(), on_construct = function(pos) - local meta = minetest.get_meta(pos) - local inv = meta:get_inventory() - for _, element in pairs(elements) do - inv:set_size("armor_"..element, 1) - end + spawn_stand_entity(pos) + end, + on_destruct = function(pos) + drop_inventory(pos) end, - -- Drop all armor on the ground when it got destroyed - on_destruct = drop_armor, - -- Put piece of armor on armor stand, or take one away on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + print(pos, node, clicker, itemstack, pointed_thing) local protname = clicker:get_player_name() + if minetest.is_protected(pos, protname) then minetest.record_protection_violation(pos, protname) return itemstack end - local inv = minetest.get_inventory({type = "node", pos = pos}) - if not inv then - return itemstack - end - - -- Check if player wields armor - local name = itemstack:get_name() - local list - for e=1, #elements do - local g = minetest.get_item_group(name, "armor_" .. elements[e]) - if g ~= nil and g ~= 0 then - list = "armor_" .. elements[e] - break - end - end - -- If player wields armor, put it on armor stand - local wielditem = clicker:get_wielded_item() - if list then - -- ... but only if the slot is free - local single_item = ItemStack(itemstack) - single_item:set_count(1) - if inv:is_empty(list) then - inv:add_item(list, single_item) - mcl_armor.play_equip_sound(single_item, nil, pos) - update_entity(pos) - itemstack:take_item() - return itemstack - end - end - - -- Take armor from stand if player has a free hand or wields the same armor type (if stackable) - for e=1, #elements do - local stand_armor = inv:get_stack("armor_" .. elements[e], 1) - if not stand_armor:is_empty() then - local pinv = clicker:get_inventory() - local taken = false - -- Empty hand - if wielditem:get_name() == "" then - pinv:set_stack("main", clicker:get_wield_index(), stand_armor) - taken = true - -- Stackable armor type (if not already full). This is the case for e.g. mob heads. - -- This is done purely for convenience. - elseif (wielditem:get_name() == stand_armor:get_name() and wielditem:get_count() < wielditem:get_stack_max()) then - wielditem:set_count(wielditem:get_count()+1) - pinv:set_stack("main", clicker:get_wield_index(), wielditem) - taken = true - end - if taken then - mcl_armor.play_equip_sound(stand_armor, nil, pos, true) - stand_armor:take_item() - inv:set_stack("armor_" .. elements[e], 1, stand_armor) - end - update_entity(pos) - return clicker:get_wielded_item() - end - end - update_entity(pos) - return itemstack - end, - after_place_node = function(pos) - minetest.add_entity(pos, "mcl_armor_stand:armor_entity") - end, - allow_metadata_inventory_take = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - else - return stack:get_count() - end - end, - allow_metadata_inventory_put = function(pos, listname, index, stack, player) - local name = player:get_player_name() - if minetest.is_protected(pos, name) then - minetest.record_protection_violation(pos, name) - return 0 - end - local def = stack:get_definition() or {} - local groups = def.groups or {} - if groups[listname] then - return 1 - end - return 0 - end, - allow_metadata_inventory_move = function() - return 0 - end, - on_metadata_inventory_put = function(pos) - update_entity(pos) - end, - on_metadata_inventory_take = function(pos) - update_entity(pos) - end, - after_destruct = function(pos) - update_entity(pos) - end, - on_blast = function(pos, _, do_drop) - local object = get_stand_object(pos) - if object then - object:remove() - end - minetest.after(1, function(pos) - update_entity(pos) - end, pos) - minetest.remove_node(pos) - if do_drop then - minetest.add_item(pos, "mcl_armor_stand:armor_stand") - end + return mcl_armor.equip(itemstack, get_stand_entity(pos, node).object, true) end, on_rotate = function(pos, node, user, mode) if mode == screwdriver.ROTATE_FACE then node.param2 = (node.param2 + 1) % 4 minetest.swap_node(pos, node) - update_entity(pos) + get_stand_entity(pos, node):update_rotation(node) return true end return false @@ -224,52 +96,43 @@ minetest.register_node("mcl_armor_stand:armor_stand", { }) minetest.register_entity("mcl_armor_stand:armor_entity", { - physical = true, - visual = "mesh", - mesh = "3d_armor_entity.obj", - visual_size = {x=1, y=1}, - collisionbox = {-0.1,-0.4,-0.1, 0.1,1.3,0.1}, - pointable = false, - textures = {"blank.png"}, - pos = nil, - timer = 0, - on_activate = function(self, staticdata) - self.object:set_armor_groups({immortal=1}) - local pos = self.object:get_pos() - self.pos = vector.round(pos) - self.inventory = minetest.get_meta(pos):get_inventory() - update_entity(pos) + initial_properties = { + physical = true, + visual = "mesh", + mesh = "3d_armor_entity.obj", + visual_size = {x=1, y=1}, + collisionbox = {-0.1,-0.4,-0.1, 0.1,1.3,0.1}, + pointable = false, + textures = {"blank.png"}, + timer = 0, + static_save = false, + }, + on_activate = function(self) + self.object:set_armor_groups({immortal = 1}) + self.node_pos = vector.round(self.object:get_pos()) + self.inventory = minetest.get_meta(self.node_pos):get_inventory() + migrate_inventory(self.inventory) + end, + on_step = function(self, dtime) + if minetest.get_node(self.node_pos).name ~= "mcl_armor_stand:armor_stand" then + self.object:remove() + end end, update_armor = function(self, info) self.object:set_properties({textures = {info.texture}}) end, - on_step = function(self, dtime) - if not self.pos then - return - end - self.timer = self.timer + dtime - if self.timer > 1 then - self.timer = 0 - local pos = self.object:get_pos() - if pos then - if vector.equals(vector.round(pos), self.pos) then - return - end - end - update_entity(self.pos) - self.object:remove() - end + update_rotation = function(self, node) + self.object:set_yaw(minetest.dir_to_yaw(minetest.facedir_to_dir(node.param2))) end, }) --- FIXME: Armor helper entity can get destroyed by /clearobjects minetest.register_lbm({ label = "Respawn armor stand entities", name = "mcl_armor_stand:respawn_entities", nodenames = {"mcl_armor_stand:armor_stand"}, run_at_every_load = true, action = function(pos, node) - update_entity(pos, node) + spawn_stand_entity(pos, node) end, }) @@ -282,7 +145,6 @@ minetest.register_craft({ } }) - -- Legacy handling minetest.register_alias("3d_armor_stand:armor_stand", "mcl_armor_stand:armor_stand") minetest.register_entity(":3d_armor_stand:armor_entity", { From d1198e8d740153f648ce885c782a90f0a2253ce6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 16:19:12 +0200 Subject: [PATCH 20/43] Register elytra texture --- mods/ITEMS/mcl_armor/register.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/mods/ITEMS/mcl_armor/register.lua b/mods/ITEMS/mcl_armor/register.lua index 91410f659..de17fd20d 100644 --- a/mods/ITEMS/mcl_armor/register.lua +++ b/mods/ITEMS/mcl_armor/register.lua @@ -201,4 +201,5 @@ minetest.register_tool("mcl_armor:elytra", { on_place = mcl_armor.equip_on_use, on_secondary_use = mcl_armor.equip_on_use, _mcl_armor_element = "torso", + _mcl_armor_texture = "mcl_armor_elytra.png" }) From 1cf53caa7a6b6949d685c1c8140a02ccfd5a9c49 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 16:20:32 +0200 Subject: [PATCH 21/43] Update armor stand entity in on_activate callback, remove debug print --- mods/ITEMS/mcl_armor_stand/init.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor_stand/init.lua b/mods/ITEMS/mcl_armor_stand/init.lua index 8bcb06134..870d567fc 100644 --- a/mods/ITEMS/mcl_armor_stand/init.lua +++ b/mods/ITEMS/mcl_armor_stand/init.lua @@ -74,7 +74,6 @@ minetest.register_node("mcl_armor_stand:armor_stand", { drop_inventory(pos) end, on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) - print(pos, node, clicker, itemstack, pointed_thing) local protname = clicker:get_player_name() if minetest.is_protected(pos, protname) then @@ -112,6 +111,7 @@ minetest.register_entity("mcl_armor_stand:armor_entity", { self.node_pos = vector.round(self.object:get_pos()) self.inventory = minetest.get_meta(self.node_pos):get_inventory() migrate_inventory(self.inventory) + mcl_armor.update(self.object) end, on_step = function(self, dtime) if minetest.get_node(self.node_pos).name ~= "mcl_armor_stand:armor_stand" then From 3ad5b30ea5d68723b7b0b9a7f84fbe85a7739569 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 17:38:19 +0200 Subject: [PATCH 22/43] Add cramming and fireworks damage types for future use --- mods/CORE/mcl_damage/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 83c6d83af..3aabbd525 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -25,6 +25,8 @@ mcl_damage = { fireball = {is_projectile = true, is_fire = true}, thorns = {is_magic = true}, explosion = {is_explosion = true}, + cramming = {bypasses_armor = true}, + fireworks = {is_explosion = true}, } } From 2827542002662aff9edae7044d3a49974b733ff2 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 18:49:00 +0200 Subject: [PATCH 23/43] Implement food poisoning damage properly~ --- mods/CORE/mcl_damage/init.lua | 6 +++--- mods/PLAYER/mcl_hunger/hunger.lua | 5 +---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 3aabbd525..18cb6cb13 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -12,7 +12,7 @@ mcl_damage = { cactus = {}, fall = {bypasses_armor = true}, fly_into_wall = {bypasses_armor = true}, -- unused - out_of_world = {bypasses_armor = true, bypasses_invulnerability = true, bypasses_magic = true}, + out_of_world = {bypasses_armor = true, bypasses_invulnerability = true}, generic = {bypasses_armor = true}, magic = {is_magic = true, bypasses_armor = true}, wither = {bypasses_armor = true}, -- unused @@ -25,8 +25,8 @@ mcl_damage = { fireball = {is_projectile = true, is_fire = true}, thorns = {is_magic = true}, explosion = {is_explosion = true}, - cramming = {bypasses_armor = true}, - fireworks = {is_explosion = true}, + cramming = {bypasses_armor = true}, -- unused + fireworks = {is_explosion = true}, -- unused } } diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index 30ad10ac2..2f192357a 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -110,10 +110,7 @@ local function poisonp(tick, time, time_left, damage, exhaustion, name) -- Deal damage and exhaust player -- TODO: Introduce fatal poison at higher difficulties if player:get_hp()-damage > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 succumbed to the poison.", name)) - end - player:set_hp(player:get_hp()-damage) + mcl_util.deal_damage(player, damage, {type = "hunger"}) end mcl_hunger.exhaust(name, exhaustion) From d08a226a51ed3001e4714f44fce5b2a35849c79a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 19:50:48 +0200 Subject: [PATCH 24/43] Integrate critical hits --- mods/CORE/mcl_damage/init.lua | 3 ++ mods/PLAYER/mcl_criticals/init.lua | 38 ++++++++++++++++++ mods/PLAYER/mcl_criticals/mod.conf | 2 + .../sounds/mcl_criticals_hit.0.ogg | Bin 0 -> 10932 bytes .../sounds/mcl_criticals_hit.1.ogg | Bin 0 -> 12936 bytes .../sounds/mcl_criticals_hit.2.ogg | Bin 0 -> 10130 bytes mods/PLAYER/mcl_playerplus/init.lua | 31 -------------- 7 files changed, 43 insertions(+), 31 deletions(-) create mode 100644 mods/PLAYER/mcl_criticals/init.lua create mode 100644 mods/PLAYER/mcl_criticals/mod.conf create mode 100644 mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg create mode 100644 mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.1.ogg create mode 100644 mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 18cb6cb13..2018ffc19 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -102,6 +102,9 @@ old_register_hpchange(function(player, hp_change, mt_reason) for _, modf in ipairs(mcl_damage.modifiers) do hp_change = modf.func(player, hp_change, mt_reason, mcl_reason) or hp_change + if hp_change == 0 then + return 0 + end end return hp_change diff --git a/mods/PLAYER/mcl_criticals/init.lua b/mods/PLAYER/mcl_criticals/init.lua new file mode 100644 index 000000000..6b420e0b8 --- /dev/null +++ b/mods/PLAYER/mcl_criticals/init.lua @@ -0,0 +1,38 @@ +mcl_criticals = {} + +function mcl_criticals.modifier(obj, hp_change, reason) + local damage = -hp_change + if damage > 0 and reason.type == "player" then + local hitter = reason.direct + if mcl_sprint.is_sprinting(hitter) then + obj:add_velocity(hitter:get_velocity()) + elseif (hitter:get_velocity() or hitter:get_player_velocity()).y < 0 then + local pos = mcl_util.get_object_center(obj) + minetest.add_particlespawner({ + amount = 15, + time = 0.1, + minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, + maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, + minvel = {x=-0.1, y=-0.1, z=-0.1}, + maxvel = {x=0.1, y=0.1, z=0.1}, + minacc = {x=0, y=0, z=0}, + maxacc = {x=0, y=0, z=0}, + minexptime = 1, + maxexptime = 2, + minsize = 1.5, + maxsize = 1.5, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", + }) + minetest.sound_play("mcl_criticals_hit", {object = obj}) + -- the minecraft wiki is actually wrong about a crit dealing 150% damage, see minecraft source code + damage = damage + math.random(0, math.floor(damage * 1.5 + 2)) + end + end + return -damage +end + +mcl_damage.register_modifier(function(player, hp_change, _, mcl_reason) + return mcl_criticals.modifier(player, hp_change, mcl_reason) +end, -100) diff --git a/mods/PLAYER/mcl_criticals/mod.conf b/mods/PLAYER/mcl_criticals/mod.conf new file mode 100644 index 000000000..5b0b91330 --- /dev/null +++ b/mods/PLAYER/mcl_criticals/mod.conf @@ -0,0 +1,2 @@ +name = mcl_criticals +depends = mcl_damage diff --git a/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.0.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8184d10768996a9faac5fcf83e29dc0f5c7445b9 GIT binary patch literal 10932 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 Kg8`8I*Z4np&^ERJ literal 0 HcmV?d00001 diff --git a/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg b/mods/PLAYER/mcl_criticals/sounds/mcl_criticals_hit.2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..6d573b9f2877a7f66b3fe4b758dcfb63d32edac2 GIT binary patch literal 10130 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 literal 0 HcmV?d00001 diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 5d74903fb..5cf0253ab 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -113,37 +113,6 @@ end local node_stand, node_stand_below, node_head, node_feet - -minetest.register_on_punchplayer(function(player, hitter, damage) - if hitter:is_player() then - if hitter:get_player_control().aux1 then - player:add_velocity(hitter:get_velocity()) - end - if hitter:get_velocity().y < -6 then - player:set_hp(player:get_hp() - (damage * math.random(0.50 , 0.75))) - local pos = player:get_pos() - minetest.add_particlespawner({ - amount = 15, - time = 0.1, - minpos = {x=pos.x-0.5, y=pos.y-0.5, z=pos.z-0.5}, - maxpos = {x=pos.x+0.5, y=pos.y+0.5, z=pos.z+0.5}, - minvel = {x=-0.1, y=-0.1, z=-0.1}, - maxvel = {x=0.1, y=0.1, z=0.1}, - minacc = {x=0, y=0, z=0}, - maxacc = {x=0, y=0, z=0}, - minexptime = 1, - maxexptime = 2, - minsize = 1.5, - maxsize = 1.5, - collisiondetection = false, - vertical = false, - texture = "mcl_particles_crit.png^[colorize:#bc7a57:127", - }) - end - end -end) - - minetest.register_globalstep(function(dtime) time = time + dtime From d9195cc520754e048202c85820511663c2df38b8 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 20:08:08 +0200 Subject: [PATCH 25/43] Redesign damage modifier execution --- mods/CORE/mcl_damage/init.lua | 83 +++++++++++++++--------------- mods/ITEMS/mcl_armor/damage.lua | 13 ++--- mods/ITEMS/mcl_armor/player.lua | 4 -- mods/PLAYER/mcl_criticals/init.lua | 14 ++--- 4 files changed, 48 insertions(+), 66 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 2018ffc19..7f8469c3e 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -15,7 +15,7 @@ mcl_damage = { out_of_world = {bypasses_armor = true, bypasses_invulnerability = true}, generic = {bypasses_armor = true}, magic = {is_magic = true, bypasses_armor = true}, - wither = {bypasses_armor = true}, -- unused + wither = {bypasses_armor = true}, -- unused anvil = {}, falling_node = {}, -- unused dragon_breath = {bypasses_armor = true}, -- unused @@ -30,24 +30,45 @@ mcl_damage = { } } -local old_register_hpchange = minetest.register_on_player_hpchange - -function minetest.register_on_player_hpchange(func, modifier) - if modifier then - mcl_damage.register_modifier(func, 0) - else - old_register_hpchange(func, modifier) - end -end - function mcl_damage.register_modifier(func, priority) table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0}) end -function mcl_damage.get_mcl_damage_reason(mt_reason) - local mcl_reason = { - type = "generic", - } +function mcl_damage.do_modifiers(player, damage, reason) + for _, modf in ipairs(mcl_damage.modifiers) do + damage = modf.func(player, damage, reason) or damage + if damage == 0 then + return 0 + end + end + + return damage +end + +function mcl_damage.from_punch(mcl_reason, object) + mcl_reason.direct = object + local luaentity = mcl_reason.direct:get_luaentity() + if luaentity then + if luaentity._is_arrow then + mcl_reason.type = "arrow" + elseif luaentity._is_fireball then + mcl_reason.type = "fireball" + elseif luaentity._cmi_is_mob then + mcl_reason.type = "mob" + end + mcl_reason.source = mcl_reason.source or luaentity._source_object + else + mcl_reason.type = "player" + end +end + +function mcl_damage.finish_reason(mcl_reason) + mcl_reason.source = mcl_reason.source or mcl_reason.direct + mcl_reason.flags = mcl_damage.types[mcl_reason.type] +end + +function mcl_damage.from_mt(mt_reason) + local mcl_reason = {type = "generic"} if mt_reason._mcl_type then mcl_reason.type = mt_reason._mcl_type @@ -56,22 +77,7 @@ function mcl_damage.get_mcl_damage_reason(mt_reason) elseif mt_reason.type == "drown" then mcl_reason.type = "drown" elseif mt_reason.type == "punch" then - mcl_reason.direct = mt_reason.object - if mcl_reason.direct then - local luaentity = mcl_reason.direct:get_luaentity() - if luaentity then - if luaentity._is_arrow then - mcl_reason.type = "arrow" - elseif luaentity._is_fireball then - mcl_reason.type = "fireball" - elseif luaentity._cmi_is_mob then - mcl_reason.type = "mob" - end - mcl_reason.source = mcl_reason.source or luaentity._source_object - else - mcl_reason.type = "player" - end - end + mcl_damage.from_punch(mcl_reason, mt_reason.object) elseif mt_reason.type == "node_damage" and mt_reason.node then if minetest.get_item_group(mt_reason.node, "fire") > 0 then mcl_reason.type = "in_fire" @@ -87,8 +93,7 @@ function mcl_damage.get_mcl_damage_reason(mt_reason) end end - mcl_reason.source = mcl_reason.source or mcl_reason.direct - mcl_reason.flags = mcl_damage.types[mcl_reason.type] + mcl_damage.finish_reason(mcl_reason) return mcl_reason end @@ -97,16 +102,10 @@ function mcl_damage.register_type(name, def) mcl_damage.types[name] = def end -old_register_hpchange(function(player, hp_change, mt_reason) - local mcl_reason = mcl_damage.get_mcl_damage_reason(mt_reason) - - for _, modf in ipairs(mcl_damage.modifiers) do - hp_change = modf.func(player, hp_change, mt_reason, mcl_reason) or hp_change - if hp_change == 0 then - return 0 - end +minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if hp_change < 0 then + hp_change = -mcl_damage.do_modifiers(player, -hp_change, mcl_damage.from_mt(mt_reason)) end - return hp_change end, true) diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index e6d13dfa7..3715538ec 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -1,13 +1,8 @@ -function mcl_armor.damage_modifier(obj, hp_change, reason) - if hp_change > 0 then - return hp_change - end - - local damage = -hp_change +mcl_damage.register_modifier(function(obj, damage, reason) local flags = reason.flags if flags.bypasses_armor and flags.bypasses_magic then - return hp_change + return damage end local uses = math.max(1, math.floor(damage / 4)) @@ -95,5 +90,5 @@ function mcl_armor.damage_modifier(obj, hp_change, reason) mcl_armor.update(obj) - return -math.floor(damage + 0.5) -end + return math.floor(damage + 0.5) +end, 0) diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 50828fcea..4d90ec0e2 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -155,7 +155,3 @@ end) minetest.register_on_leaveplayer(function(player) mcl_armor.player_view_range_factors[player] = nil end) - -mcl_damage.register_modifier(function(player, hp_change, _, reason) - return mcl_armor.damage_modifier(player, hp_change, reason) -end) diff --git a/mods/PLAYER/mcl_criticals/init.lua b/mods/PLAYER/mcl_criticals/init.lua index 6b420e0b8..27d09abb2 100644 --- a/mods/PLAYER/mcl_criticals/init.lua +++ b/mods/PLAYER/mcl_criticals/init.lua @@ -1,8 +1,5 @@ -mcl_criticals = {} - -function mcl_criticals.modifier(obj, hp_change, reason) - local damage = -hp_change - if damage > 0 and reason.type == "player" then +mcl_damage.register_modifier(function(obj, damage, reason) + if reason.type == "player" then local hitter = reason.direct if mcl_sprint.is_sprinting(hitter) then obj:add_velocity(hitter:get_velocity()) @@ -27,12 +24,7 @@ function mcl_criticals.modifier(obj, hp_change, reason) }) minetest.sound_play("mcl_criticals_hit", {object = obj}) -- the minecraft wiki is actually wrong about a crit dealing 150% damage, see minecraft source code - damage = damage + math.random(0, math.floor(damage * 1.5 + 2)) + return damage + math.random(0, math.floor(damage * 1.5 + 2)) end end - return -damage -end - -mcl_damage.register_modifier(function(player, hp_change, _, mcl_reason) - return mcl_criticals.modifier(player, hp_change, mcl_reason) end, -100) From 53b0ad734725edf27909a26b93035eee783e666f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 20:21:11 +0200 Subject: [PATCH 26/43] Implement magic damage --- mods/CORE/mcl_util/init.lua | 10 ++++++++++ mods/ITEMS/mcl_potions/functions.lua | 20 ++++---------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 49d1c82a1..741dc604e 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -503,6 +503,16 @@ function mcl_util.deal_damage(target, damage, mcl_reason) target:set_hp(target:get_hp() - damage, mt_reason) end +function mcl_util.get_hp(obj) + local luaentity = obj:get_luaentity() + + if luaentity and luaentity._cmi_is_mob then + return luaentity.health + else + return obj:get_hp() + end +end + function mcl_util.get_inventory(object, create) if object:is_player() then return object:get_inventory() diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 769e5f5b9..9f0c88782 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -132,17 +132,10 @@ minetest.register_globalstep(function(dtime) if player:get_pos() then mcl_potions._add_spawner(player, "#225533") end if EF.poisoned[player].hit_timer >= EF.poisoned[player].step then - - if entity and entity._cmi_is_mob then - entity.health = math.max(entity.health - 1, 1) - EF.poisoned[player].hit_timer = 0 - elseif is_player then - player:set_hp( math.max(player:get_hp() - 1, 1), { type = "punch", other = "poison"}) - EF.poisoned[player].hit_timer = 0 - else -- if not player or mob then remove - EF.poisoned[player] = nil + if mcl_util.get_hp(player) - 1 > 0 then + mcl_util.deal_damage(player, 1, {type = "magic"}) end - + EF.poisoned[player].hit_timer = 0 end if EF.poisoned[player] and EF.poisoned[player].timer >= EF.poisoned[player].dur then @@ -721,12 +714,7 @@ function mcl_potions.healing_func(player, hp) hp = -1 end - if obj and obj._cmi_is_mob then - obj.health = obj.health + hp - elseif player:is_player() then - player:set_hp(player:get_hp() + hp, { type = "punch", other = "harming" }) - end - + mcl_util.deal_damage(obj, -hp, {type = "magic"}) end end From c9b4ddb9237330be28542b90c6ec94f20dc2a1a6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 18 Apr 2021 20:22:18 +0200 Subject: [PATCH 27/43] Add command damage type (This is Non-MC) --- mods/CORE/mcl_damage/init.lua | 1 + mods/MISC/mcl_commands/kill.lua | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 7f8469c3e..bc5280841 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -27,6 +27,7 @@ mcl_damage = { explosion = {is_explosion = true}, cramming = {bypasses_armor = true}, -- unused fireworks = {is_explosion = true}, -- unused + command = {bypasses_armor = true, bypasses_invulnerability = true, bypasses_magic = true}, } } diff --git a/mods/MISC/mcl_commands/kill.lua b/mods/MISC/mcl_commands/kill.lua index 2de69e6a0..3eac565d6 100644 --- a/mods/MISC/mcl_commands/kill.lua +++ b/mods/MISC/mcl_commands/kill.lua @@ -31,7 +31,7 @@ local function handle_kill_command(suspect, victim) mcl_death_messages.player_damage(victimref, msg) end -- DIE! - victimref:set_hp(0) + victimref:set_hp(0, {_mcl_type = "command"}) -- Log if not suspect == victim then minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) @@ -56,4 +56,4 @@ minetest.register_chatcommand("kill", { return handle_kill_command(name, param) end end, -}) \ No newline at end of file +}) From 69485f8505a7beccb9d4cec7ab6fc3f31e93eab3 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 19 Apr 2021 09:49:29 +0200 Subject: [PATCH 28/43] Integrate falling nodes damage --- mods/ENTITIES/mcl_falling_nodes/init.lua | 102 ++++++----------------- 1 file changed, 27 insertions(+), 75 deletions(-) diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 6e69f8911..831434d62 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -2,8 +2,6 @@ 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 is_creative_enabled = minetest.is_creative_enabled - local get_falling_depth = function(self) if not self._startpos then -- Fallback @@ -23,80 +21,34 @@ local deal_falling_damage = function(self, dtime) -- Fallback self._startpos = pos end - local objs = minetest.get_objects_inside_radius(pos, 1) - for _,v in ipairs(objs) do - if v:is_player() then - local hp = v:get_hp() - local name = v:get_player_name() - if hp ~= 0 then - if not self._hit_players then - self._hit_players = {} - end - local hit = false - for _,v in ipairs(self._hit_players) do - if name == v then - hit = true + self._hit = self._hit or {} + for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do + if mcl_util.get_hp(obj) > 0 and not self._hit[obj] then + self._hit[obj] = true + local way = self._startpos.y - pos.y + local damage = (way - 1) * 2 + damage = math.min(40, math.max(0, damage)) + if damage >= 1 then + -- Reduce damage if wearing a helmet + local inv = mcl_util.get_inventory(obj) + if inv then + local helmet = inv:get_stack("armor", 2) + if minetest.get_item_group(helmet:get_name(), "combat_armor") > 0 then + damage = damage / 4 * 3 + mcl_util.use_item_durability(helmet, 1) + inv:set_stack("armor", 2, helmet) 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 - 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 is_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()) - else - msg = S("@1 was smashed by a falling block.", v:get_player_name()) - end - if dmes then - mcl_death_messages.player_damage(v, msg) - end - v:set_hp(hp, { type = "punch", from = "mod" }) - end + local deathmsg, dmg_type + if minetest.get_item_group(self.node.name, "anvil") ~= 0 then + deathmsg, dmg_type = "@1 was smashed by a falling anvil.", "anvil" + else + deathmsg, dmg_type = "@1 was smashed by a falling block.", "falling_node" 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 + if obj:is_player() then + mcl_death_messages.player_damage(obj, S(deathmsg, obj:get_player_name())) end + mcl_util.deal_damage(obj, damage, {type = dmg_type}) end end end @@ -166,7 +118,7 @@ minetest.register_entity(":__builtin:falling_node", { on_activate = function(self, staticdata) self.object:set_armor_groups({immortal = 1}) - + local ds = minetest.deserialize(staticdata) if ds then self._startpos = ds._startpos @@ -200,7 +152,7 @@ minetest.register_entity(":__builtin:falling_node", { local np = {x = pos.x, y = pos.y + 0.3, z = pos.z} local n2 = minetest.get_node(np) if n2.name == "mcl_portals:portal_end" then - -- TODO: Teleport falling node. + -- TODO: Teleport falling node. self.object:remove() return end @@ -239,7 +191,7 @@ minetest.register_entity(":__builtin:falling_node", { end local nd = minetest.registered_nodes[n2.name] if n2.name == "mcl_portals:portal_end" then - -- TODO: Teleport falling node. + -- TODO: Teleport falling node. elseif (nd and nd.buildable_to == true) or minetest.get_item_group(self.node.name, "crush_after_fall") ~= 0 then -- Replace destination node if it's buildable to From 4c250914309da4226aa36efad50ab0a2757fa0d6 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Mon, 19 Apr 2021 19:12:32 +0200 Subject: [PATCH 29/43] Fix syntax error in mcl_inventory --- mods/HUD/mcl_inventory/creative.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 43a818f6a..61ba39b10 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -7,7 +7,7 @@ local players = {} -- Containing all the items for each Creative Mode tab local inventory_lists = {} -+local mod_player = minetest.get_modpath("mcl_player") ~= nil +local mod_player = minetest.get_modpath("mcl_player") ~= nil -- Create tables local builtin_filter_ids = {"blocks","deco","redstone","rail","food","tools","combat","mobs","brew","matr","misc","all"} From dccb71e2fb91600779a7d3db4ad588ce948ea2a3 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 21 Apr 2021 11:34:22 +0200 Subject: [PATCH 30/43] Fix view_range_factors warning --- mods/ITEMS/mcl_armor/player.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index 4d90ec0e2..e5471e7e1 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -64,7 +64,7 @@ function mcl_armor.update_player(player, info) local meta = player:get_meta() meta:set_int("mcl_armor:armor_points", info.points) - mcl_armor.player_view_range_factors[player] = view_range_factors + mcl_armor.player_view_range_factors[player] = info.view_range_factors end local function is_armor_action(inventory_info) From 74a3b2654f5e45783c8d9b6c243f3855fc697a0a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Wed, 21 Apr 2021 13:28:22 +0200 Subject: [PATCH 31/43] Create inventory if not present in mcl_armor.equip --- mods/ITEMS/mcl_armor/api.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index c3a84f265..4f2b2593a 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -44,7 +44,7 @@ function mcl_armor.equip(itemstack, obj, swap) end local element = mcl_armor.elements[def._mcl_armor_element or ""] - local inv = mcl_util.get_inventory(obj) + local inv = mcl_util.get_inventory(obj, true) if element and inv then local old_stack = inv:get_stack("armor", element.index) From 222104b3cbe419b04c209ff2257a2030df6ec2d4 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 22 Apr 2021 13:51:36 +0200 Subject: [PATCH 32/43] Integrate dispensers --- mods/ITEMS/REDSTONE/mcl_dispensers/init.lua | 91 ++++----------------- 1 file changed, 15 insertions(+), 76 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua index faf2ff742..02ed70aed 100644 --- a/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua +++ b/mods/ITEMS/REDSTONE/mcl_dispensers/init.lua @@ -136,93 +136,32 @@ local dispenserdef = { -- Hardcoded dispensions -- -- Armor, mob heads and pumpkins - if igroups.armor_head or igroups.armor_torso or igroups.armor_legs or igroups.armor_feet then - local armor_type, armor_slot - local armor_dispensed = false - if igroups.armor_head then - armor_type = "armor_head" - armor_slot = 2 - elseif igroups.armor_torso then - armor_type = "armor_torso" - armor_slot = 3 - elseif igroups.armor_legs then - armor_type = "armor_legs" - armor_slot = 4 - elseif igroups.armor_feet then - armor_type = "armor_feet" - armor_slot = 5 - end + if igroups.armor then + local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z} - local droppos_below = {x=droppos.x, y=droppos.y-1, z=droppos.z} - local dropnode_below = minetest.get_node(droppos_below) - -- Put armor on player or armor stand - local standpos - if dropnode.name == "mcl_armor_stand:armor_stand" then - standpos = droppos - elseif dropnode_below.name == "mcl_armor_stand:armor_stand" then - standpos = droppos_below - end - if standpos then - local dropmeta = minetest.get_meta(standpos) - local dropinv = dropmeta:get_inventory() - if dropinv:room_for_item(armor_type, dropitem) then - dropinv:add_item(armor_type, dropitem) - minetest.registered_nodes["mcl_armor_stand:armor_stand"].on_metadata_inventory_put(standpos) - stack:take_item() - inv:set_stack("main", stack_id, stack) - mcl_armor.play_equip_sound(dropitem, nil, standpos) - armor_dispensed = true - end - else - -- Put armor on nearby player - -- First search for player in front of dispenser (check 2 nodes) - local objs1 = minetest.get_objects_inside_radius(droppos, 1) - local objs2 = minetest.get_objects_inside_radius(droppos_below, 1) - local objs_table = {objs1, objs2} - local player - for oi=1, #objs_table do - local objs_inner = objs_table[oi] - for o=1, #objs_inner do - --[[ First player in list is the lucky one. The other player get nothing :-( - If multiple players are close to the dispenser, it can be a bit - -- unpredictable on who gets the armor. ]] - if objs_inner[o]:is_player() then - player = objs_inner[o] - break - end - end - if player then + for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do + for _, obj in ipairs(objs) do + stack = mcl_armor.equip(stack, obj) + if stack:is_empty() then break end end - -- If player found, add armor - if player then - local ainv = minetest.get_inventory({type="detached", name=player:get_player_name().."_armor"}) - local pinv = player:get_inventory() - if ainv:get_stack("armor", armor_slot):is_empty() and pinv:get_stack("armor", armor_slot):is_empty() then - ainv:set_stack("armor", armor_slot, dropitem) - pinv:set_stack("armor", armor_slot, dropitem) - mcl_armor.update(player) - mcl_armor.play_equip_sound(dropitem, player) - - stack:take_item() - inv:set_stack("main", stack_id, stack) - armor_dispensed = true - end + if stack:is_empty() then + break end + end -- Place head or pumpkin as node, if equipping it as armor has failed - if not armor_dispensed then - if igroups.head or iname == "mcl_farming:pumpkin_face" then - if dropnodedef.buildable_to then - minetest.set_node(droppos, {name = iname, param2 = node.param2}) - stack:take_item() - inv:set_stack("main", stack_id, stack) - end + if not stack:is_empty() then + if igroups.head or iname == "mcl_farming:pumpkin_face" then + if dropnodedef.buildable_to then + minetest.set_node(droppos, {name = iname, param2 = node.param2}) + stack:take_item() end end end + inv:set_stack("main", stack_id, stack) -- Spawn Egg elseif igroups.spawn_egg then -- Spawn mob From f9c2d710e2196d078ec8a7f2323d618a7af22be5 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Thu, 22 Apr 2021 13:52:02 +0200 Subject: [PATCH 33/43] Fix armor being taken even if it cannot be equipped --- mods/ITEMS/mcl_armor/api.lua | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index 4f2b2593a..d56e3188d 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -43,22 +43,25 @@ function mcl_armor.equip(itemstack, obj, swap) return itemstack end - local element = mcl_armor.elements[def._mcl_armor_element or ""] local inv = mcl_util.get_inventory(obj, true) - if element and inv then + if not inv or inv:get_size("armor") == 0 then + return itemstack + end + + local element = mcl_armor.elements[def._mcl_armor_element or ""] + + if element then local old_stack = inv:get_stack("armor", element.index) local new_stack if swap then new_stack = itemstack itemstack = old_stack - else - new_stack = itemstack:take_item() end if swap or old_stack:is_empty() then - inv:set_stack("armor", element.index, new_stack) + inv:set_stack("armor", element.index, new_stack or itemstack:take_item()) mcl_armor.on_equip(new_stack, obj) end end From 50b6f039776fe7e885dc608afb1cd001fdc26346 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 23 Apr 2021 12:34:24 +0200 Subject: [PATCH 34/43] Integrate no fall damage in water & end portal --- mods/PLAYER/mcl_player/init.lua | 59 ----------------------------- mods/PLAYER/mcl_playerplus/init.lua | 58 ++++++++++++++++++++++++++++ mods/PLAYER/mcl_playerplus/mod.conf | 2 +- 3 files changed, 59 insertions(+), 60 deletions(-) diff --git a/mods/PLAYER/mcl_player/init.lua b/mods/PLAYER/mcl_player/init.lua index 3c0151737..6cf2f0014 100644 --- a/mods/PLAYER/mcl_player/init.lua +++ b/mods/PLAYER/mcl_player/init.lua @@ -243,62 +243,3 @@ minetest.register_globalstep(function(dtime) end end end) - --- Don't change HP if the player falls in the water or through End Portal: -minetest.register_on_player_hpchange(function(player, hp_change, reason) - if reason and reason.type == "fall" and player then - local pos = player:get_pos() - local node = minetest.get_node(pos) - local velocity = player:get_velocity() or player:get_player_velocity() or {x=0,y=-10,z=0} - local v_axis_max = math.max(math.abs(velocity.x), math.abs(velocity.y), math.abs(velocity.z)) - local step = {x = velocity.x / v_axis_max, y = velocity.y / v_axis_max, z = velocity.z / v_axis_max} - for i = 1, math.ceil(v_axis_max/5)+1 do -- trace at least 1/5 of the way per second - if not node or node.name == "ignore" then - minetest.get_voxel_manip():read_from_map(pos, pos) - node = minetest.get_node(pos) - end - if node then - if minetest.registered_nodes[node.name].walkable then - return hp_change - end - if minetest.get_item_group(node.name, "water") ~= 0 then - return 0 - end - if node.name == "mcl_portals:portal_end" then - if mcl_portals and mcl_portals.end_teleport then - mcl_portals.end_teleport(player) - end - return 0 - end - end - pos = vector.add(pos, step) - node = minetest.get_node(pos) - end - end - return hp_change -end, true) - -minetest.register_on_respawnplayer(function(player) - local pos = player:get_pos() - minetest.add_particlespawner({ - amount = 50, - time = 0.001, - minpos = vector.add(pos, 0), - maxpos = vector.add(pos, 0), - minvel = vector.new(-5,-5,-5), - maxvel = vector.new(5,5,5), - minexptime = 1.1, - maxexptime = 1.5, - minsize = 1, - maxsize = 2, - collisiondetection = false, - vertical = false, - texture = "mcl_particles_mob_death.png^[colorize:#000000:255", - }) - - minetest.sound_play("mcl_mobs_mob_poof", { - pos = pos, - gain = 1.0, - max_hear_distance = 8, - }, true) -end) diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index e74c36829..a748abaac 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -497,3 +497,61 @@ minetest.register_on_leaveplayer(function(player) mcl_playerplus_internal[name] = nil mcl_playerplus.elytra[player] = nil end) + +-- Don't change HP if the player falls in the water or through End Portal: +mcl_damage.register_modifier(function(obj, damage, reason) + if reason.type == "fall" then + local pos = obj:get_pos() + local node = minetest.get_node(pos) + local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0} + local v_axis_max = math.max(math.abs(velocity.x), math.abs(velocity.y), math.abs(velocity.z)) + local step = {x = velocity.x / v_axis_max, y = velocity.y / v_axis_max, z = velocity.z / v_axis_max} + for i = 1, math.ceil(v_axis_max/5)+1 do -- trace at least 1/5 of the way per second + if not node or node.name == "ignore" then + minetest.get_voxel_manip():read_from_map(pos, pos) + node = minetest.get_node(pos) + end + if node then + if minetest.registered_nodes[node.name].walkable then + return + end + if minetest.get_item_group(node.name, "water") ~= 0 then + return 0 + end + if node.name == "mcl_portals:portal_end" then + if mcl_portals and mcl_portals.end_teleport then + mcl_portals.end_teleport(obj) + end + return 0 + end + end + pos = vector.add(pos, step) + node = minetest.get_node(pos) + end + end +end, -200) + +minetest.register_on_respawnplayer(function(player) + local pos = player:get_pos() + minetest.add_particlespawner({ + amount = 50, + time = 0.001, + minpos = vector.add(pos, 0), + maxpos = vector.add(pos, 0), + minvel = vector.new(-5,-5,-5), + maxvel = vector.new(5,5,5), + minexptime = 1.1, + maxexptime = 1.5, + minsize = 1, + maxsize = 2, + collisiondetection = false, + vertical = false, + texture = "mcl_particles_mob_death.png^[colorize:#000000:255", + }) + + minetest.sound_play("mcl_mobs_mob_poof", { + pos = pos, + gain = 1.0, + max_hear_distance = 8, + }, true) +end) diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 95121f8ea..6cc9c68db 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1,5 +1,5 @@ name = mcl_playerplus author = TenPlus1 description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. -depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, mcl_death_messages, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting +depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, mcl_death_messages, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage From 78355c5c578a89fac2b1fc2b455fd9395f276a7b Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Fri, 23 Apr 2021 13:40:51 +0200 Subject: [PATCH 35/43] Integrate totems --- mods/ENTITIES/mobs_mc/1_items_default.lua | 62 +---------------------- mods/ITEMS/mcl_totems/init.lua | 61 ++++++++++++++++++++-- mods/ITEMS/mcl_totems/mod.conf | 2 +- 3 files changed, 59 insertions(+), 66 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/1_items_default.lua b/mods/ENTITIES/mobs_mc/1_items_default.lua index b4abd4f9c..bdadbfdc5 100644 --- a/mods/ENTITIES/mobs_mc/1_items_default.lua +++ b/mods/ENTITIES/mobs_mc/1_items_default.lua @@ -516,8 +516,6 @@ end -- Evoker if c("totem") then - local hud_totem = {} - -- Totem of Undying minetest.register_craftitem("mobs_mc:totem", { description = S("Totem of Undying"), @@ -527,66 +525,8 @@ if c("totem") then inventory_image = "mcl_totems_totem.png", wield_image = "mcl_totems_totem.png", stack_max = 1, + groups = {combat_item=1}, }) - - minetest.register_on_leaveplayer(function(player) - hud_totem[player:get_player_name()] = nil - end) - - -- Save the player from death when holding totem of undying in hand - minetest.register_on_player_hpchange(function(player, hp_change) - local hp = player:get_hp() - -- Fatal damage? - if hp + hp_change <= 0 then - local wield = player:get_wielded_item() - if wield:get_name() == "mobs_mc:totem" then - local ppos = player:get_pos() - local pnname = minetest.get_node(ppos).name - -- Some exceptions when _not_ to save the player - for n=1, #mobs_mc.misc.totem_fail_nodes do - if pnname == mobs_mc.misc.totem_fail_nodes[n] then - return hp_change - end - end - -- Reset breath as well - if player:get_breath() < 11 then - player:set_breath(10) - end - if not minetest.is_creative_enabled(player:get_player_name()) then - wield:take_item() - player:set_wielded_item(wield) - end - -- Effects - minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) - - -- Big totem overlay - if not hud_totem[player:get_player_name()] then - hud_totem[player:get_player_name()] = player:hud_add({ - hud_elem_type = "image", - text = "mcl_totems_totem.png", - position = { x=0.5, y=1 }, - scale = { x=17, y=17 }, - offset = { x=0, y=-178 }, - z_index = 100, - }) - minetest.after(3, function(name) - local player = minetest.get_player_by_name(name) - if player and player:is_player() then - local name = player:get_player_name() - if hud_totem[name] then - player:hud_remove(hud_totem[name]) - hud_totem[name] = nil - end - end - end, player:get_player_name()) - end - - -- Set HP to exactly 1 - return -hp + 1 - end - end - return hp_change - end, true) end -- Rotten flesh diff --git a/mods/ITEMS/mcl_totems/init.lua b/mods/ITEMS/mcl_totems/init.lua index b4ec3eb8d..499d7362d 100644 --- a/mods/ITEMS/mcl_totems/init.lua +++ b/mods/ITEMS/mcl_totems/init.lua @@ -1,5 +1,58 @@ --- Node is currently defined in mobs_mc. --- TODO: Add full item definition here when status effects become a thing. +local hud_totem = {} --- Add group for Creative Mode. -minetest.override_item("mobs_mc:totem", {groups = { combat_item=1}}) +minetest.register_on_leaveplayer(function(player) + hud_totem[player] = nil +end) + +-- Save the player from death when holding totem of undying in hand +mcl_damage.register_modifier(function(obj, damage, reason) + if obj:is_player() then + local hp = obj:get_hp() + if hp - damage <= 0 then + local wield = obj:get_wielded_item() + if wield:get_name() == "mobs_mc:totem" then + local ppos = obj:get_pos() + local pnname = minetest.get_node(ppos).name + -- Some exceptions when _not_ to save the player + for n=1, #mobs_mc.misc.totem_fail_nodes do + if pnname == mobs_mc.misc.totem_fail_nodes[n] then + return + end + end + -- Reset breath as well + if obj:get_breath() < 11 then + obj:set_breath(10) + end + + if not minetest.is_creative_enabled(obj:get_player_name()) then + wield:take_item() + obj:set_wielded_item(wield) + end + + -- Effects + minetest.sound_play({name = "mcl_totems_totem", gain=1}, {pos=ppos, max_hear_distance=16}, true) + + -- Big totem overlay + if not hud_totem[obj] then + hud_totem[obj] = obj:hud_add({ + hud_elem_type = "image", + text = "mcl_totems_totem.png", + position = { x=0.5, y=1 }, + scale = { x=17, y=17 }, + offset = { x=0, y=-178 }, + z_index = 100, + }) + minetest.after(3, function() + if obj:is_player() then + obj:hud_remove(hud_totem[obj]) + hud_totem[obj] = nil + end + end) + end + + -- Set HP to exactly 1 + return hp - 1 + end + end + end +end, 1000) diff --git a/mods/ITEMS/mcl_totems/mod.conf b/mods/ITEMS/mcl_totems/mod.conf index 70c5844c6..4ba94defc 100644 --- a/mods/ITEMS/mcl_totems/mod.conf +++ b/mods/ITEMS/mcl_totems/mod.conf @@ -1,2 +1,2 @@ name = mcl_totems -depends = mobs_mc +depends = mobs_mc, mcl_damage From 939229cb213de3e031cabaebc43e7bcfd6c4a88e Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 13:29:22 +0200 Subject: [PATCH 36/43] Fix on_equip crash --- mods/ITEMS/mcl_armor/api.lua | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/mods/ITEMS/mcl_armor/api.lua b/mods/ITEMS/mcl_armor/api.lua index d56e3188d..4d6686807 100644 --- a/mods/ITEMS/mcl_armor/api.lua +++ b/mods/ITEMS/mcl_armor/api.lua @@ -53,15 +53,18 @@ function mcl_armor.equip(itemstack, obj, swap) if element then local old_stack = inv:get_stack("armor", element.index) - local new_stack - - if swap then - new_stack = itemstack - itemstack = old_stack - end if swap or old_stack:is_empty() then - inv:set_stack("armor", element.index, new_stack or itemstack:take_item()) + local new_stack + + if swap then + new_stack = itemstack + itemstack = old_stack + else + new_stack = itemstack:take_item() + end + + inv:set_stack("armor", element.index, new_stack) mcl_armor.on_equip(new_stack, obj) end end From 6aecae6eea436849b9a80dbfa99bb0aa42c31d84 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 13:50:07 +0200 Subject: [PATCH 37/43] Simplify damage pipeline; Add on_death and on_damage callbacks --- mods/CORE/mcl_damage/init.lua | 48 ++++++++++++++++++++++++++++++++--- mods/CORE/mcl_util/init.lua | 21 ++++----------- 2 files changed, 50 insertions(+), 19 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index bc5280841..24c5fb42c 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -1,5 +1,7 @@ mcl_damage = { modifiers = {}, + damage_callbacks = {}, + death_callbacks = {}, types = { in_fire = {is_fire = true}, lightning_bolt = {is_lightning = true}, @@ -35,9 +37,17 @@ function mcl_damage.register_modifier(func, priority) table.insert(mcl_damage.modifiers, {func = func, priority = priority or 0}) end -function mcl_damage.do_modifiers(player, damage, reason) +function mcl_damage.register_on_damage(func) + table.insert(mcl_damage.damage_callbacks, func) +end + +function mcl_damage.register_on_death(func) + table.insert(mcl_damage.death_callbacks, func) +end + +function mcl_damage.run_modifiers(obj, damage, reason) for _, modf in ipairs(mcl_damage.modifiers) do - damage = modf.func(player, damage, reason) or damage + damage = modf.func(obj, damage, reason) or damage if damage == 0 then return 0 end @@ -46,6 +56,20 @@ function mcl_damage.do_modifiers(player, damage, reason) return damage end +local function run_callbacks(funcs, ...) + for _, func in pairs(funcs) do + func(...) + end +end + +function mcl_damage.run_damage_callbacks(obj, damage, reason) + run_callbacks(mcl_damage.damage_callbacks, obj, damage, reason) +end + +function mcl_damage.run_death_callbacks(obj, reason) + run_callbacks(mcl_damage.death_callbacks, obj, reason) +end + function mcl_damage.from_punch(mcl_reason, object) mcl_reason.direct = object local luaentity = mcl_reason.direct:get_luaentity() @@ -69,6 +93,10 @@ function mcl_damage.finish_reason(mcl_reason) end function mcl_damage.from_mt(mt_reason) + if mt_reason._mcl_reason then + return mt_reason._mcl_reason + end + local mcl_reason = {type = "generic"} if mt_reason._mcl_type then @@ -95,6 +123,7 @@ function mcl_damage.from_mt(mt_reason) end mcl_damage.finish_reason(mcl_reason) + mt_reason._mcl_reason = mcl_reason return mcl_reason end @@ -105,11 +134,24 @@ end minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) if hp_change < 0 then - hp_change = -mcl_damage.do_modifiers(player, -hp_change, mcl_damage.from_mt(mt_reason)) + if player:get_hp() <= 0 then + return 0 + end + hp_change = -mcl_damage.run_modifiers(player, -hp_change, mcl_damage.from_mt(mt_reason)) end return hp_change end, true) +minetest.register_on_player_hpchange(function(player, hp_change, mt_reason) + if hp_change < 0 then + mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason)) + end +end, false) + +minetest.register_on_dieplayer(function(player, mt_reason) + mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason)) +end) + minetest.register_on_mods_loaded(function() table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) end) diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index 741dc604e..a2a1ea816 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -475,32 +475,21 @@ function mcl_util.use_item_durability(itemstack, n) end function mcl_util.deal_damage(target, damage, mcl_reason) - mcl_reason = mcl_reason or {} - local luaentity = target:get_luaentity() if luaentity then if luaentity.deal_damage then - luaentity:deal_damage(damage, mcl_reason) + luaentity:deal_damage(damage, mcl_reason or {type = "generic"}) return elseif luaentity._cmi_is_mob then - local puncher = mcl_reason.direct or target - target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage) + -- local puncher = mcl_reason and mcl_reason.direct or target + -- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage) + luaentity.health = luaentity.health - damage return end end - local mt_reason - - if target:is_player() then - mt_reason = {} - - for key, value in pairs(mcl_reason) do - mt_reason["_mcl_" .. key] = value - end - end - - target:set_hp(target:get_hp() - damage, mt_reason) + target:set_hp(target:get_hp() - damage, {_mcl_reason = mcl_reason}) end function mcl_util.get_hp(obj) From 302175691ae3634dda3a2c998705b0316b73757f Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 16:42:38 +0200 Subject: [PATCH 38/43] Integrate death messages --- mods/CORE/mcl_damage/init.lua | 8 +- mods/CORE/mcl_explosions/init.lua | 4 - mods/CORE/mcl_util/init.lua | 19 + mods/ENTITIES/mcl_burning/api.lua | 15 +- mods/ENTITIES/mcl_falling_nodes/init.lua | 8 +- mods/ENTITIES/mobs_mc/blaze.lua | 2 +- mods/ENVIRONMENT/lightning/init.lua | 4 - mods/ENVIRONMENT/lightning/mod.conf | 1 - mods/ENVIRONMENT/mcl_void_damage/init.lua | 2 - mods/ENVIRONMENT/mcl_void_damage/mod.conf | 2 +- mods/HUD/mcl_death_messages/init.lua | 459 ++++++++++----------- mods/ITEMS/mcl_armor/damage.lua | 4 +- mods/ITEMS/mcl_enchanting/enchantments.lua | 2 +- mods/ITEMS/mcl_nether/init.lua | 4 - mods/ITEMS/mcl_nether/mod.conf | 2 +- mods/ITEMS/mcl_tnt/mod.conf | 2 +- mods/MISC/mcl_commands/kill.lua | 12 +- mods/MISC/mcl_commands/mod.conf | 1 - mods/PLAYER/mcl_hunger/hunger.lua | 1 - mods/PLAYER/mcl_hunger/init.lua | 4 - mods/PLAYER/mcl_hunger/mod.conf | 1 - mods/PLAYER/mcl_playerinfo/mod.conf | 2 +- mods/PLAYER/mcl_playerplus/init.lua | 2 - mods/PLAYER/mcl_playerplus/mod.conf | 2 +- 24 files changed, 247 insertions(+), 316 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 24c5fb42c..6b343c4c2 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -14,13 +14,14 @@ mcl_damage = { cactus = {}, fall = {bypasses_armor = true}, fly_into_wall = {bypasses_armor = true}, -- unused - out_of_world = {bypasses_armor = true, bypasses_invulnerability = true}, + out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true}, generic = {bypasses_armor = true}, magic = {is_magic = true, bypasses_armor = true}, + dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable wither = {bypasses_armor = true}, -- unused + wither_skull = {is_magic = true, is_explosion = true}, -- this is non-MC but a workaround to get the proper death message anvil = {}, - falling_node = {}, -- unused - dragon_breath = {bypasses_armor = true}, -- unused + falling_node = {}, -- this is falling_block in MC mob = {}, player = {}, arrow = {is_projectile = true}, @@ -29,7 +30,6 @@ mcl_damage = { explosion = {is_explosion = true}, cramming = {bypasses_armor = true}, -- unused fireworks = {is_explosion = true}, -- unused - command = {bypasses_armor = true, bypasses_invulnerability = true, bypasses_magic = true}, } } diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 52499215e..e59e3ea12 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -12,7 +12,6 @@ under the LGPLv2.1 license. mcl_explosions = {} -local mod_death_messages = minetest.get_modpath("mcl_death_messages") ~= nil local mod_fire = minetest.get_modpath("mcl_fire") ~= nil local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire") @@ -333,9 +332,6 @@ local function trace_explode(pos, strength, raydirs, radius, info, direct, sourc sleep_formspec_doesnt_close_mt53 = true end end - if mod_death_messages then - mcl_death_messages.player_damage(obj, S("@1 was caught in an explosion.", name)) - end end if sleep_formspec_doesnt_close_mt53 then diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a2a1ea816..f619b5465 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -516,3 +516,22 @@ function mcl_util.get_inventory(object, create) return inventory end end + +function mcl_util.get_wielded_item(object) + if object:is_player() then + return object:get_wielded_item() + else + -- ToDo: implement getting wielditems from mobs as soon as mobs have wielditems + return ItemStack() + end +end + +function mcl_util.get_object_name(object) + if object:is_player() then + return object:get_player_name() + else + local luaentity = object:get_luaentity() + + return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name + end +end diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 21875619c..0d299cc69 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -35,7 +35,7 @@ function mcl_burning.get_touching_nodes(obj, nodenames, storage) return nodes end -function mcl_burning.set_on_fire(obj, burn_time, reason) +function mcl_burning.set_on_fire(obj, burn_time) if obj:get_hp() < 0 then return end @@ -52,7 +52,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) else local max_fire_prot_lvl = 0 local inv = mcl_util.get_inventory(obj) - local armor_list = inv and inv:get_list("armor") + local armor_list = inv and inv:get_list("armor") if armor_list then for _, stack in pairs(armor_list) do @@ -79,7 +79,6 @@ function mcl_burning.set_on_fire(obj, burn_time, reason) }) end storage.burn_time = burn_time - storage.burn_reason = reason storage.fire_damage_timer = 0 local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire") @@ -120,7 +119,6 @@ function mcl_burning.extinguish(obj) mcl_burning.storage[obj] = {} else storage.burn_time = nil - storage.burn_reason = nil storage.fire_damage_timer = nil end end @@ -140,20 +138,13 @@ function mcl_burning.tick(obj, dtime, storage) storage.fire_damage_timer = 0 local hp = mcl_util.get_hp(obj) - + if hp > 0 then local do_damage = true if obj:is_player() then if mcl_potions.player_has_effect(obj, "fire_proof") then do_damage = false - else - local name = obj:get_player_name() - local deathmsg = S("@1 burned to death.", name) - if storage.reason then - deathmsg = S("@1 was burned by @2.", name, storage.reason) - end - mcl_death_messages.player_damage(obj, deathmsg) end elseif obj:get_luaentity().fire_damage_resistant then do_damage = false diff --git a/mods/ENTITIES/mcl_falling_nodes/init.lua b/mods/ENTITIES/mcl_falling_nodes/init.lua index 831434d62..af2c06703 100644 --- a/mods/ENTITIES/mcl_falling_nodes/init.lua +++ b/mods/ENTITIES/mcl_falling_nodes/init.lua @@ -1,5 +1,4 @@ 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 get_falling_depth = function(self) @@ -41,12 +40,9 @@ local deal_falling_damage = function(self, dtime) end local deathmsg, dmg_type if minetest.get_item_group(self.node.name, "anvil") ~= 0 then - deathmsg, dmg_type = "@1 was smashed by a falling anvil.", "anvil" + dmg_type = "anvil" else - deathmsg, dmg_type = "@1 was smashed by a falling block.", "falling_node" - end - if obj:is_player() then - mcl_death_messages.player_damage(obj, S(deathmsg, obj:get_player_name())) + dmg_type = "falling_node" end mcl_util.deal_damage(obj, damage, {type = dmg_type}) end diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 4595ce5a7..876237f19 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -151,7 +151,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", { -- Direct hit, no fire... just plenty of pain hit_player = function(self, player) - mcl_burning.set_on_fire(player, 5, "blaze") + mcl_burning.set_on_fire(player, 5) player:punch(self.object, 1.0, { full_punch_interval = 1.0, damage_groups = {fleshy = 5}, diff --git a/mods/ENVIRONMENT/lightning/init.lua b/mods/ENVIRONMENT/lightning/init.lua index 64a304dbe..4a58866f9 100644 --- a/mods/ENVIRONMENT/lightning/init.lua +++ b/mods/ENVIRONMENT/lightning/init.lua @@ -11,7 +11,6 @@ of the license, or (at your option) any later version. local S = minetest.get_translator("lightning") -local has_mcl_death_msg = minetest.get_modpath("mcl_death_messages") local get_connected_players = minetest.get_connected_players local line_of_sight = minetest.line_of_sight local get_node = minetest.get_node @@ -171,9 +170,6 @@ lightning.strike = function(pos) obj:set_yaw(rot) -- Other objects: Just damage else - if obj:is_player() and has_mcl_death_msg then - mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name())) - end mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"}) end end diff --git a/mods/ENVIRONMENT/lightning/mod.conf b/mods/ENVIRONMENT/lightning/mod.conf index b0d756318..346a4a0b9 100644 --- a/mods/ENVIRONMENT/lightning/mod.conf +++ b/mods/ENVIRONMENT/lightning/mod.conf @@ -2,5 +2,4 @@ name = lightning author = sofar description = A mod that adds thunder and lightning effects. depends = mcl_fire -optional_depends = mcl_death_messages diff --git a/mods/ENVIRONMENT/mcl_void_damage/init.lua b/mods/ENVIRONMENT/mcl_void_damage/init.lua index ac39d10ba..24f7d0e4b 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/init.lua +++ b/mods/ENVIRONMENT/mcl_void_damage/init.lua @@ -5,7 +5,6 @@ local pos_to_dim = mcl_worlds.pos_to_dimension local dim_change = mcl_worlds.dimension_change local is_in_void = mcl_worlds.is_in_void local get_spawn_pos = mcl_spawn.get_player_spawn_pos -local death_msg = mcl_death_messages.player_damage local send_chat = minetest.chat_send_player local get_connected = minetest.get_connected_players @@ -79,7 +78,6 @@ minetest.register_globalstep(function(dtime) elseif enable_damage and not is_immortal then -- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds) if player:get_hp() > 0 then - death_msg(player, S("@1 fell into the endless void.", player:get_player_name())) mcl_util.deal_damage(player, VOID_DAMAGE, {type = "out_of_world"}) end end diff --git a/mods/ENVIRONMENT/mcl_void_damage/mod.conf b/mods/ENVIRONMENT/mcl_void_damage/mod.conf index 3f34fa5a1..1358e5217 100644 --- a/mods/ENVIRONMENT/mcl_void_damage/mod.conf +++ b/mods/ENVIRONMENT/mcl_void_damage/mod.conf @@ -1,4 +1,4 @@ name = mcl_void_damage author = Wuzzy description = Deal damage to entities stuck in the deep void -depends = mcl_worlds, mcl_death_messages +depends = mcl_worlds diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 6fd7e0c93..874af7754 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,81 +1,157 @@ local S = minetest.get_translator("mcl_death_messages") -local N = function(s) return s end -local C = minetest.colorize -local color_skyblue = mcl_colors.AQUA - -local function get_tool_name(item) - local name = item:get_meta():get_string("name") - if name ~= "" then - return name - end - local def = item:get_definition() - return def._tt_original_description or def.description - end - -mcl_death_messages = {} - --- Death messages -local msgs = { - ["arrow"] = { - N("@1 was fatally hit by an arrow."), - N("@1 has been killed by an arrow."), +mcl_death_messages = { + messages = { + in_fire = { + _translator = S, + plain = "@1 went up in flames", + escape = "@1 walked into fire whilst fighting @2", + }, + lightning_bolt = { + _translator = S, + plain = "@1 was struck by lightning", + escape = "@1 was struck by lightning whilst fighting @2", + }, + on_fire = { + _translator = S, + plain = "@1 burned to death", + escape = "@1 was burnt to a crisp whilst fighting @2", + }, + lava = { + _translator = S, + plain = "@1 tried to swim in lava", + escape = "@1 tried to swim in lava to escape @2" + }, + hot_floor = { + _translator = S, + plain = "@1 discovered the floor was lava", + escape = "@1 walked into danger zone due to @2", + }, + in_wall = { + _translator = S, + plain = "@1 suffocated in a wall", + escape = "@1 suffocated in a wall whilst fighting @2", + }, + drown = { + _translator = S, + plain = "@1 drowned", + escape = "@1 drowned whilst trying to escape @2", + }, + starve = { + _translator = S, + plain = "@1 starved to death", + escape = "@1 starved to death whilst fighting @2", + }, + cactus = { + _translator = S, + plain = "@1 was pricked to death", + escape = "@1 walked into a cactus whilst trying to escape @2", + }, + fall = { + _translator = S, + plain = "@1 hit the ground too hard", + escape = "@1 hit the ground too hard whilst trying to escape @2", + -- "@1 fell from a high place" -- for fall distance > 5 blocks + -- "@1 fell while climbing" + -- "@1 fell off some twisting vines" + -- "@1 fell off some weeping vines" + -- "@1 fell off some vines" + -- "@1 fell off scaffolding" + -- "@1 fell off a ladder" + }, + fly_into_wall = { + _translator = S, + plain = "@1 experienced kinetic energy", + escape = "@1 experienced kinetic energy whilst trying to escape @2", + }, + out_of_world = { + _translator = S, + plain = "@1 fell out of the world", + escape = "@1 didn't want to live in the same world as @2", + }, + generic = { + _translator = S, + plain = "@1 died", + escape = "@1 died because of @2", + }, + magic = { + _translator = S, + plain = "@1 was killed by magic", + escape = "@1 was killed by magic whilst trying to escape @2", + killer = "@1 was killed by @2 using magic", + item = "@1 was killed by @2 using @3", + }, + dragon_breath = { + _translator = S, + plain = "@1 was roasted in dragon breath", + killer = "@1 was roasted in dragon breath by @2", + }, + wither = { + _translator = S, + plain = "@1 withered away", + escape = "@1 withered away whilst fighting @2", + }, + wither_skull = { + _translator = S, + plain = "@1 was killed by magic", + killer = "@1 was shot by a skull from @2", + }, + anvil = { + _translator = S, + plain = "@1 was squashed by a falling anvil", + escape = "@1 was squashed by a falling anvil whilst fighting @2", + }, + falling_node = { + _translator = S, + plain = "@1 was squashed by a falling block", + escape = "@1 was squashed by a falling block whilst fighting @2", + }, + mob = { + _translator = S, + killer = "@1 was slain by @2", + item = "@1 was slain by @2 using @3", + }, + player = { + _translator = S, + killer = "@1 was slain by @2", + item = "@1 was slain by @2 using @3" + }, + arrow = { + _translator = S, + killer = "@1 was shot by @2", + item = "@1 was shot by @2 using @3", + }, + fireball = { + _translator = S, + killer = "@1 was fireballed by @2", + item = "@1 was fireballed by @2 using @3", + }, + thorns = { + _translator = S, + killer = "@1 was killed trying to hurt @2", + item = "@1 was killed by @3 trying to hurt @2", -- yes, the order is intentional: @1 @3 @2 + }, + explosion = { + _translator = S, + plain = "@1 blew up", + killer = "@1 was blown up by @2", + item = "@1 was blown up by @2 using @3", + -- "@1 was killed by [Intentional Game Design]" -- for exploding bed in nether or end + }, + cramming = { + _translator = S, + plain = "@1 was squished too much", + escape = "@1 was squashed by @2", -- surprisingly "escape" is actually the correct subtype + }, + fireworks = { + _translator = S, + plain = "@1 went off with a bang", + item = "@1 went off with a bang due to a firework fired from @3 by @2", -- order is intentional + }, + -- Missing snowballs: The Minecraft wiki mentions them but the MC source code does not. }, - ["arrow_name"] = { - N("@1 was shot by @2 using [@3]"), - }, - ["arrow_skeleton"] = { - N("@1 was shot by Skeleton."), - }, - ["arrow_stray"] = { - N("@1 was shot by Stray."), - }, - ["arrow_illusioner"] = { - N("@1 was shot by Illusioner."), - }, - ["arrow_mob"] = { - N("@1 was shot."), - }, - ["drown"] = { - N("@1 forgot to breathe."), - N("@1 drowned."), - N("@1 ran out of oxygen."), - }, - ["murder"] = { - N("@1 was slain by @2 using [@3]"), - }, - ["murder_hand"] = { - N("@1 was slain by @2"), - }, - ["murder_any"] = { - N("@1 was killed."), - }, - ["mob_kill"] = { - N("@1 was slain by a mob."), - }, - ["blaze_fireball"] = { - N("@1 was burned to death by a Blaze's fireball."), - N("@1 was fireballed by a Blaze"), - }, - ["fire_charge"] = { - N("@1 was burned by a fire charge."), - }, - ["ghast_fireball"] = { - N("A Ghast scared @1 to death."), - N("@1 has been fireballed by a Ghast."), - }, - ["fall"] = { - N("@1 fell from a high cliff."), - N("@1 took fatal fall damage."), - N("@1 fell victim to gravity."), - N("@1 hit the ground too hard.") - }, - - ["other"] = { - N("@1 died."), - } } - +--[[ local mobkills = { ["mobs_mc:zombie"] = N("@1 was slain by Zombie."), ["mobs_mc:baby_zombie"] = N("@1 was slain by Baby Zombie."), @@ -117,191 +193,74 @@ local mobkills = { ["mobs_mc:pigman"] = N("@1 was slain by Zombie Pigman."), ["mobs_mc:baby_pigman"] = N("@1 was slain by Baby Zombie Pigman."), } +]]-- --- Select death message -local dmsg = function(mtype, ...) - local r = math.random(1, #msgs[mtype]) - return S(msgs[mtype][r], ...) -end - --- Select death message for death by mob -local mmsg = function(mtype, ...) - if mobkills[mtype] then - return S(mobkills[mtype], ...) - else - return dmsg("mob_kill", ...) +local function get_item_killer_message(obj, messages, reason) + if messages.item then + local wielded = mcl_util.get_wielded_item(reason.source) + local itemname = wielded:get_meta():get_string("name") + if itemname ~= "" then + itemname = "[" .. itemname .. "]" + if mcl_enchanting.is_enchanted(wielded:get_name()) then + itemname = minetest.colorize(mcl_colors.AQUA, itemname) + end + return messages._translator(messages.item, mcl_util.get_object_name(obj), mcl_util.get_object_name(reason.source), itemname) + end end end -local last_damages = { } +local function get_plain_killer_message(obj, messages, reason) + return messages.killer and messages._translator(messages.killer, mcl_util.get_object_name(obj), mcl_util.get_object_name(reason.source)) +end -minetest.register_on_dieplayer(function(player, reason) - -- Death message - local message = minetest.settings:get_bool("mcl_showDeathMessages") --Maybe cache the setting? - if message == nil then - message = true +local function get_killer_message(obj, messages, reason) + return reason.source and (get_item_killer_message(obj, messages, reason) or get_plain_killer_message(obj, messages, reason)) +end + +local function get_escaped_message(obj, messages, reason) + return nil -- ToDo +end + +local function get_plain_message(obj, messages, reason) + if messages.plain then + return messages._translator(messages.plain, mcl_util.get_object_name(obj)) end - if message then - local name = player:get_player_name() - if not name then - return - end - local msg - if last_damages[name] then - -- custom message - msg = last_damages[name].message - elseif reason.type == "node_damage" then - local pos = player:get_pos() - -- Check multiple nodes because players occupy multiple nodes - -- (we add one additional node because the check may fail if the player was - -- just barely touching the node with the head) - local posses = { pos, {x=pos.x,y=pos.y+1,z=pos.z}, {x=pos.x,y=pos.y+2,z=pos.z}} - local highest_damage = 0 - local highest_damage_def = nil - -- Show message for node that dealt the most damage - for p=1, #posses do - local def = minetest.registered_nodes[minetest.get_node(posses[p]).name] - local dmg = def.damage_per_second - if dmg and dmg > highest_damage then - highest_damage = dmg - highest_damage_def = def - end - end - if highest_damage_def and highest_damage_def._mcl_node_death_message then - local field = highest_damage_def._mcl_node_death_message - local field_msg - if type(field) == "table" then - field_msg = field[math.random(1, #field)] - else - field_msg = field - end - local textdomain - if highest_damage_def.mod_origin then - textdomain = highest_damage_def.mod_origin - else - textdomain = "mcl_death_messages" - end - -- We assume the textdomain of the death message in the node definition - -- equals the modname. - msg = minetest.translate(textdomain, field_msg, name) - end - elseif reason.type == "drown" then - msg = dmsg("drown", name) - elseif reason.type == "punch" then - -- Punches - local hitter = reason.object +end - -- Player was slain by potions - if not hitter then return end +local function get_fallback_message(obj, messages, reason) + return "mcl_death_messages.messages." .. reason.type .. " " .. mcl_util.get_object_name(obj) +end - local hittername, hittertype, hittersubtype, shooter - local hitter_toolname = get_tool_name(hitter:get_wielded_item()) +local function fallback_translator(s) + return s +end - -- Custom message - if last_damages[name] then - msg = last_damages[name].message - -- Unknown hitter - elseif hitter == nil then - msg = dmsg("murder_any", name) - -- Player - elseif hitter:is_player() then - hittername = hitter:get_player_name() - if hittername ~= nil then - if hitter_toolname == "" then - msg = dmsg("murder_hand", name, hittername) - else - msg = dmsg("murder", name, hittername, C(color_skyblue, hitter_toolname)) - end - else - msg = dmsg("murder_any", name) - end - -- Mob (according to Common Mob Interface) - elseif hitter:get_luaentity()._cmi_is_mob then - if hitter:get_luaentity().nametag and hitter:get_luaentity().nametag ~= "" then - hittername = hitter:get_luaentity().nametag - end - hittersubtype = hitter:get_luaentity().name - if hittername then - msg = dmsg("murder_hand", name, hittername) - elseif hittersubtype ~= nil and hittersubtype ~= "" then - msg = mmsg(hittersubtype, name) - else - msg = dmsg("murder_any", name) - end - -- Arrow - elseif hitter:get_luaentity().name == "mcl_bows:arrow_entity" or hitter:get_luaentity().name == "mobs_mc:arrow_entity" and not killed_by_potion then - local shooter - if hitter:get_luaentity()._shooter then - shooter = hitter:get_luaentity()._shooter - end - local is_mob = false - local s_ent = shooter and shooter:get_luaentity() - if shooter == nil then - msg = dmsg("arrow", name) - elseif shooter:is_player() then - msg = dmsg("arrow_name", name, shooter:get_player_name(), C(color_skyblue, get_tool_name(shooter:get_wielded_item()))) - elseif s_ent and s_ent._cmi_is_mob then - if s_ent.nametag ~= "" then - msg = dmsg("arrow_name", name, shooter:get_player_name(), get_tool_name(shooter:get_wielded_item())) - elseif s_ent.name == "mobs_mc:skeleton" then - msg = dmsg("arrow_skeleton", name) - elseif s_ent.name == "mobs_mc:stray" then - msg = dmsg("arrow_stray", name) - elseif s_ent.name == "mobs_mc:illusioner" then - msg = dmsg("arrow_illusioner", name) - else - msg = dmsg("arrow_mob", name) - end - else - msg = dmsg("arrow", name) - end - -- Blaze fireball - elseif hitter:get_luaentity().name == "mobs_mc:blaze_fireball" then - if hitter:get_luaentity()._shot_from_dispenser then - msg = dmsg("fire_charge", name) - else - msg = dmsg("blaze_fireball", name) - end - -- Ghast fireball - elseif hitter:get_luaentity().name == "mobs_monster:fireball" then - msg = dmsg("ghast_fireball", name) - end - -- Falling - elseif reason.type == "fall" then - msg = dmsg("fall", name) - -- Other - elseif reason.type == "set_hp" then - if last_damages[name] then - msg = last_damages[name].message - end +mcl_damage.register_on_death(function(obj, reason) + if not minetest.settings:get_bool("mcl_showDeathMessages", true) then + return + end + + local send_to + + if obj:is_player() then + send_to = true + end -- ToDo: add mob death messages for owned mobs, only send to owner (sent_to = "player name") + + + if send_to then + local messages = mcl_death_messages.messages[reason.type] or {} + messages._translator = messages._translator or fallback_translator + + local message = + get_killer_message(obj, messages, reason) or + get_escaped_message(obj, messages, reason) or + get_plain_message(obj, messages, reason) or + get_fallback_message(obj, messages, reason) + + if send_to == true then + minetest.chat_send_all(message) + else + minetest.chat_send_player(send_to, message) end - if not msg then - msg = dmsg("other", name) - end - minetest.chat_send_all(msg) - last_damages[name] = nil end end) - --- dmg_sequence_number is used to discard old damage events -local dmg_sequence_number = 0 -local start_damage_reset_countdown = function (player, sequence_number) - minetest.after(1, function(playername, sequence_number) - if last_damages[playername] and last_damages[playername].sequence_number == sequence_number then - last_damages[playername] = nil - end - end, player:get_player_name(), sequence_number) -end - --- Send a custom death mesage when damaging a player via set_hp or punch. --- To be called directly BEFORE damaging a player via set_hp or punch. --- The next time the player dies due to a set_hp, the message will be shown. --- The player must die via set_hp within 0.1 seconds, otherwise the message will be discarded. -function mcl_death_messages.player_damage(player, message) - last_damages[player:get_player_name()] = { message = message, sequence_number = dmg_sequence_number } - start_damage_reset_countdown(player, dmg_sequence_number) - dmg_sequence_number = dmg_sequence_number + 1 - if dmg_sequence_number >= 65535 then - dmg_sequence_number = 0 - end -end diff --git a/mods/ITEMS/mcl_armor/damage.lua b/mods/ITEMS/mcl_armor/damage.lua index 3715538ec..c5023deb5 100644 --- a/mods/ITEMS/mcl_armor/damage.lua +++ b/mods/ITEMS/mcl_armor/damage.lua @@ -80,8 +80,8 @@ mcl_damage.register_modifier(function(obj, damage, reason) local thorns_damage = thorns_damage_regular + thorns_damage_irregular - if thorns_damage > 0 and reason.source ~= obj then - mcl_util.deal_damage(reason.source, {type = "thorns", direct = obj, source = reason.source}) + if thorns_damage > 0 and reason.type ~= "thorns" and reason.source ~= obj then + mcl_util.deal_damage(reason.source, {type = "thorns", direct = obj}) local thorns_item = thorns_pieces[math.random(#thorns_pieces)] mcl_util.use_item_durability(thorns_item.itemstack, 2) diff --git a/mods/ITEMS/mcl_enchanting/enchantments.lua b/mods/ITEMS/mcl_enchanting/enchantments.lua index 6fb1d079a..84327e3f6 100644 --- a/mods/ITEMS/mcl_enchanting/enchantments.lua +++ b/mods/ITEMS/mcl_enchanting/enchantments.lua @@ -132,7 +132,7 @@ minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, if wielditem then local fire_aspect_level = mcl_enchanting.get_enchantment(wielditem, "fire_aspect") if fire_aspect_level > 0 then - mcl_burning.set_on_fire(player, fire_aspect_level * 4, hitter:get_player_name()) + mcl_burning.set_on_fire(player, fire_aspect_level * 4) end end end diff --git a/mods/ITEMS/mcl_nether/init.lua b/mods/ITEMS/mcl_nether/init.lua index b6285ceb4..0a0e2b183 100644 --- a/mods/ITEMS/mcl_nether/init.lua +++ b/mods/ITEMS/mcl_nether/init.lua @@ -1,6 +1,5 @@ local S = minetest.get_translator("mcl_nether") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") local mod_screwdriver = minetest.get_modpath("screwdriver") ~= nil local on_rotate if mod_screwdriver then @@ -111,9 +110,6 @@ minetest.register_node("mcl_nether:magma", { end -- Hurt players standing on top of this block if player:get_hp() > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 stood too long on a magma block.", player:get_player_name())) - end mcl_util.deal_damage(player, 1, {type = "hot_floor"}) end end, diff --git a/mods/ITEMS/mcl_nether/mod.conf b/mods/ITEMS/mcl_nether/mod.conf index 8bef6c6c9..f5ffa61ac 100644 --- a/mods/ITEMS/mcl_nether/mod.conf +++ b/mods/ITEMS/mcl_nether/mod.conf @@ -1,3 +1,3 @@ name = mcl_nether depends = mcl_core, mcl_sounds, mcl_util, walkover, doc_items, mcl_colors -optional_depends = mcl_death_messages, doc, screwdriver +optional_depends = doc, screwdriver diff --git a/mods/ITEMS/mcl_tnt/mod.conf b/mods/ITEMS/mcl_tnt/mod.conf index 9d75a788c..2e90ddb80 100644 --- a/mods/ITEMS/mcl_tnt/mod.conf +++ b/mods/ITEMS/mcl_tnt/mod.conf @@ -1,3 +1,3 @@ name = mcl_tnt depends = mcl_explosions, mcl_particles -optional_depends = mcl_sounds, mcl_mobitems, mcl_death_messages, doc_identifier, mesecons +optional_depends = mcl_sounds, mcl_mobitems, doc_identifier, mesecons diff --git a/mods/MISC/mcl_commands/kill.lua b/mods/MISC/mcl_commands/kill.lua index 3eac565d6..85754a0ec 100644 --- a/mods/MISC/mcl_commands/kill.lua +++ b/mods/MISC/mcl_commands/kill.lua @@ -1,5 +1,4 @@ local S = minetest.get_translator("mcl_commands") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") local function handle_kill_command(suspect, victim) if minetest.settings:get_bool("enable_damage") == false then @@ -21,17 +20,8 @@ local function handle_kill_command(suspect, victim) if wield:get_name() == "mobs_mc:totem" then victimref:set_wielded_item("") end - if mod_death_messages then - local msg - if suspect == victim then - msg = S("@1 committed suicide.", victim) - else - msg = S("@1 was killed by @2.", victim, suspect) - end - mcl_death_messages.player_damage(victimref, msg) - end -- DIE! - victimref:set_hp(0, {_mcl_type = "command"}) + victimref:set_hp(0, {_mcl_type = "out_of_world"}) -- Log if not suspect == victim then minetest.log("action", string.format("%s killed %s using /kill", suspect, victim)) diff --git a/mods/MISC/mcl_commands/mod.conf b/mods/MISC/mcl_commands/mod.conf index d651fad7b..00d707098 100644 --- a/mods/MISC/mcl_commands/mod.conf +++ b/mods/MISC/mcl_commands/mod.conf @@ -1,4 +1,3 @@ name = mcl_commands author = Wuzzy description = MCL2 commands -optional_depends = mcl_death_messages diff --git a/mods/PLAYER/mcl_hunger/hunger.lua b/mods/PLAYER/mcl_hunger/hunger.lua index 2f192357a..51d7fdaeb 100644 --- a/mods/PLAYER/mcl_hunger/hunger.lua +++ b/mods/PLAYER/mcl_hunger/hunger.lua @@ -1,5 +1,4 @@ local S = minetest.get_translator("mcl_hunger") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") -- wrapper for minetest.item_eat (this way we make sure other mods can't break this one) minetest.do_item_eat = function(hp_change, replace_with_item, itemstack, user, pointed_thing) diff --git a/mods/PLAYER/mcl_hunger/init.lua b/mods/PLAYER/mcl_hunger/init.lua index 84eff255c..6b9998574 100644 --- a/mods/PLAYER/mcl_hunger/init.lua +++ b/mods/PLAYER/mcl_hunger/init.lua @@ -1,5 +1,4 @@ local S = minetest.get_translator("mcl_hunger") -local mod_death_messages = minetest.get_modpath("mcl_death_messages") mcl_hunger = {} @@ -159,9 +158,6 @@ minetest.register_globalstep(function(dtime) -- Damage hungry player down to 1 HP -- TODO: Allow starvation at higher difficulty levels if hp-1 > 0 then - if mod_death_messages then - mcl_death_messages.player_damage(player, S("@1 starved to death.", name)) - end mcl_util.deal_damage(player, 1, {type = "starve"}) end end diff --git a/mods/PLAYER/mcl_hunger/mod.conf b/mods/PLAYER/mcl_hunger/mod.conf index 7795da7a2..99ab71ff3 100644 --- a/mods/PLAYER/mcl_hunger/mod.conf +++ b/mods/PLAYER/mcl_hunger/mod.conf @@ -2,4 +2,3 @@ name = mcl_hunger author = BlockMen description = Adds a simple hunger meachanic with satiation, food poisoning and different healing. depends = hudbars -optional_depends = mcl_death_messages diff --git a/mods/PLAYER/mcl_playerinfo/mod.conf b/mods/PLAYER/mcl_playerinfo/mod.conf index 9f2b0c4a5..25c05f03e 100644 --- a/mods/PLAYER/mcl_playerinfo/mod.conf +++ b/mods/PLAYER/mcl_playerinfo/mod.conf @@ -1,4 +1,4 @@ name = mcl_playerinfo author = TenPlus1 description = This is a helper mod for other mod to query the nodes around the player. -depends = mcl_init, mcl_core, mcl_particles, mcl_death_messages +depends = mcl_init, mcl_core, mcl_particles diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua index 7dbb93215..a483a027a 100644 --- a/mods/PLAYER/mcl_playerplus/init.lua +++ b/mods/PLAYER/mcl_playerplus/init.lua @@ -391,7 +391,6 @@ minetest.register_globalstep(function(dtime) -- Check privilege, too and (not check_player_privs(name, {noclip = true})) then if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 suffocated to death.", name)) mcl_util.deal_damage(player, 1, {type = "in_wall"}) end end @@ -407,7 +406,6 @@ minetest.register_globalstep(function(dtime) local dist_feet = vector.distance({x=pos.x, y=pos.y-1, z=pos.z}, near) if dist < 1.1 or dist_feet < 1.1 then if player:get_hp() > 0 then - mcl_death_messages.player_damage(player, S("@1 was prickled to death by a cactus.", name)) mcl_util.deal_damage(player, 1, {type = "cactus"}) end end diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf index 6cc9c68db..6989957d7 100644 --- a/mods/PLAYER/mcl_playerplus/mod.conf +++ b/mods/PLAYER/mcl_playerplus/mod.conf @@ -1,5 +1,5 @@ name = mcl_playerplus author = TenPlus1 description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more. -depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, mcl_death_messages, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage +depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage From aeaec68c1be199dcac2a039798b1ce1b9aed1736 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 17:11:47 +0200 Subject: [PATCH 39/43] Update german translations for mcl_death_messages --- .../locale/mcl_death_messages.de.tr | 115 +++++++++--------- .../mcl_death_messages/locale/template.txt | 115 +++++++++--------- 2 files changed, 114 insertions(+), 116 deletions(-) diff --git a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr index ffb567b8b..39235dff7 100644 --- a/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr +++ b/mods/HUD/mcl_death_messages/locale/mcl_death_messages.de.tr @@ -1,59 +1,58 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.=@1 wurde tödlich von einem Pfeil getroffen. -@1 has been killed by an arrow.=@1 wurde von einem Pfeil getötet. -@1 was shot by an arrow from @2.=@1 wurde mit einem Pfeil von @2 abgeschossen. -@1 was shot by an arrow from a skeleton.=@1 wurde von einem Skelett mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow from a stray.=@1 wurde von einem Eiswanderer mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow from an illusioner.=@1 wurde von einem Illusionisten mit Pfeil und Bogen abgeschossen. -@1 was shot by an arrow.=@1 wurde mit einem Pfeil abgeschossen. -@1 forgot to breathe.=@1 vergaß, zu atmen. -@1 drowned.=@1 ertrank. -@1 ran out of oxygen.=@1 ging die Luft aus. -@1 was killed by @2.=@1 wurde von @2 getötet. -@1 was killed.=@1 wurde getötet. -@1 was killed by a mob.=@1 wurde von einem Mob getötet. -@1 was burned to death by a blaze's fireball.=@1 wurde von einem Feuerball einer Lohe zu Tode verbrannt. -@1 was killed by a fireball from a blaze.=@1 wurde von einem Feuerball einer Lohe getötet. -@1 was burned by a fire charge.=@1 wurde von einer Feuerkugel verbrannt. -A ghast scared @1 to death.=Ein Ghast hat @1 zu Tode erschrocken. -@1 has been fireballed by a ghast.=@1 wurde von einem Ghast mit einer Feuerkugel abgeschossen. -@1 fell from a high cliff.=@1 stürzte von einer hohen Klippe. -@1 took fatal fall damage.=@1 nahm tödlichen Fallschaden. -@1 fell victim to gravity.=@1 fiel der Schwerkraft zum Opfer. -@1 died.=@1 starb. -@1 was killed by a zombie.=@1 wurde von einem Zombie getötet. -@1 was killed by a baby zombie.=@1 wurde von einem Zombiebaby getötet. -@1 was killed by a blaze.=@1 wurde von einer Lohe getötet. -@1 was killed by a slime.=@1 wurde von einem Schleim getötet. -@1 was killed by a witch.=@1 wurde von einer Hexe getötet. -@1 was killed by a magma cube.=@1 wurde von einem Magmakubus getötet. -@1 was killed by a wolf.=@1 wurde von einem Wolf getötet. -@1 was killed by a cat.=@1 wurde von einer Katze getötet. -@1 was killed by an ocelot.=@1 wurde von einem Ozelot getötet. -@1 was killed by an ender dragon.=@1 wurde von einem Enderdrachen getötet. -@1 was killed by a wither.=@1 wurde von einem Wither getötet. -@1 was killed by an enderman.=@1 wurde von einem Enderman getötet. -@1 was killed by an endermite.=@1 wurde von einer Endermilbe getötet. -@1 was killed by a ghast.=@1 wurde von einem Ghast getötet. -@1 was killed by an elder guardian.=@1 wurde von einem Großen Wächter getötet. -@1 was killed by a guardian.=@1 wurde von einem Wächter getötet. -@1 was killed by an iron golem.=@1 wurde von einem Eisengolem getötet. -@1 was killed by a polar_bear.=@1 wurde von einem Eisbären getötet. -@1 was killed by a killer bunny.=@1 wurde von einem Killerkaninchen getötet. -@1 was killed by a shulker.=@1 wurde von einem Schulker getötet. -@1 was killed by a silverfish.=@1 wurde von einem Silberfischchen getötet. -@1 was killed by a skeleton.=@1 wurde von einem Skelett getötet. -@1 was killed by a stray.=@1 wurde von einem Eiswanderer getötet. -@1 was killed by a slime.=@1 wurde von einem Schleim getötet. -@1 was killed by a spider.=@1 wurde von einer Spinne getötet. -@1 was killed by a cave spider.=@1 wurde von einer Höhlenspinne getötet. -@1 was killed by a vex.=@1 wurde von einem Plagegeist getötet. -@1 was killed by an evoker.=@1 wurde von einem Magier getötet. -@1 was killed by an illusioner.=@1 wurde von einem Illusionisten getötet. -@1 was killed by a vindicator.=@1 wurde von einem Diener getötet. -@1 was killed by a zombie villager.=@1 wurde von einem Dorfbewohnerzombie getötet. -@1 was killed by a husk.=@1 wurde von einem Wüstenzombie getötet. -@1 was killed by a baby husk.=@1 wurde von einem Wüstenzombiebaby getötet. -@1 was killed by a zombie pigman.=@1 wurde von einem Schweinezombie getötet. -@1 was killed by a baby zombie pigman.=@1 wurde von einem Schweinezombiebaby getötet. -@1 was slain by @2.= +@1 went up in flames=@1 ging in Flammen auf +@1 walked into fire whilst fighting @2=@1 ist während eines Kampfes mit @2 in ein Feuer gelaufen +@1 was struck by lightning=@1 wurde von einem Blitz erschlagen +@1 was struck by lightning whilst fighting @2=@1 wurde während eines Kampfes mit @2 von einem Blitz erschlagen +@1 burned to death=@1 ist verbrannt +@1 was burnt to a crisp whilst fighting @2=@1 ist während eines Kampfes mit @2 verbrannt +@1 tried to swim in lava=@1 hat versucht, in Lava zu schwimmen +@1 tried to swim in lava to escape @2=@1 hat versucht, in Lava zu schwimmen, um @2 zu entkommen +@1 discovered the floor was lava=@1 hat festgestellt, dass der Boden Lava ist +@1 walked into danger zone due to @2=@1 ist wegen @2 in eine Gefahrenzone gelaufen +@1 suffocated in a wall=@1 ist in einer Mauer erstickt +@1 suffocated in a wall whilst fighting @2=@1 ist während eines Kampfes mit @2 in einer Mauer erstickt +@1 drowned=@1 ist ertrunken +@1 drowned whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, ertrunken +@1 starved to death=@1 ist verhungert +@1 starved to death whilst fighting @2=@1 ist während eines Kampfes mit @2 verhungert +@1 was pricked to death=@1 wurde zu Tode gestochen +@1 walked into a cactus whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, in einen Kaktus gelaufen +@1 hit the ground too hard=@1 ist zu hart auf dem Boden aufgetroffen +@1 hit the ground too hard whilst trying to escape @2=@1 ist während dem Versuch, @2 zu entkommen, zu hart auf dem Boden aufgetroffen +@1 experienced kinetic energy=@1 hat kinetische Energie erfahren +@1 experienced kinetic energy whilst trying to escape @2=@1 hat während dem Versuch, @2 zu entkommen, kinetische Energie erfahren +@1 fell out of the world=@1 ist aus der Welt gefallen +@1 didn't want to live in the same world as @2=@1 wollte nicht in der gleichen Welt wie @2 leben +@1 died=@1 ist gestorben +@1 died because of @2=@1 ist wegen @2 gestorben +@1 was killed by magic=@1 wurde von Magie getötet +@1 was killed by magic whilst trying to escape @2=@1 wurde während dem Versuch, @2 zu entkommen, von Magie getötet +@1 was killed by @2 using magic=@1 wurde von @2 mit Magie getötet +@1 was killed by @2 using @3=@1 wurde von @2 mit @3 getötet +@1 was roasted in dragon breath=@1 wurde in Drachenatem geröstet +@1 was roasted in dragon breath by @2=@1 wurde in Drachenatem von @2 geröstet +@1 withered away=@1 ist davon gewithert +@1 withered away whilst fighting @2=@1 ist während einem Kampf mit @2 davon gewithert +@1 was killed by magic=@1 wurde von Magie getötet +@1 was shot by a skull from @2=@1 wurde von einem Schädel von @2 erschossen +@1 was squashed by a falling anvil=@1 wurde von einem fallenden Amboss erquetscht +@1 was squashed by a falling anvil whilst fighting @2=@1 wurde während einem Kampf mit @2 von einem fallenden Amboss erquetscht +@1 was squashed by a falling block=@1 wurde von einem fallenden Block erquetscht +@1 was squashed by a falling block whilst fighting @2=@1 wurde während einem Kampf mit @2 von einem fallenden Block erquetscht +@1 was slain by @2=@1 wurde von @2 erschlagen +@1 was slain by @2 using @3=@1 wurde von @2 mit @3 erschlagen +@1 was slain by @2=@1 wurde von @2 erschlagen +@1 was slain by @2 using @3=@1 wurde von @2 mit @3 erschlagen +@1 was shot by @2=@1 wurde von @2 erschossen +@1 was shot by @2 using @3=@1 wurde von @2 mit @3 erschossen +@1 was fireballed by @2=@1 wurde von @2 gefeuerballt +@1 was fireballed by @2 using @3=@1 wurde von @2 mit @3 gefeuerballt +@1 was killed trying to hurt @2=@1 ist bei dem Versuch, @2 zu verletzten gestorben +@1 was killed by @3 trying to hurt @2=@1 ist bei dem Versuch, @2 zu verletzten, von @3 getötet worden +@1 blew up=@1 ist gesprengt worden +@1 was blown up by @2=@1 wurde von @2 gesprengt +@1 was blown up by @2 using @3=@1 wurde von @2 mit @3 gesprengt +@1 was squished too much=@1 war zu gequetscht +@1 was squashed by @2=@1 wurde von @2 erquetscht +@1 went off with a bang=@1 ging mit einem Knall ab +@1 went off with a bang due to a firework fired from @3 by @2=@1 ging mit einem Knall wegen eines Feuerwerks, das mit @3 von @2 gefeuert wurde, ab diff --git a/mods/HUD/mcl_death_messages/locale/template.txt b/mods/HUD/mcl_death_messages/locale/template.txt index d1e3b832b..67ba9fd1c 100644 --- a/mods/HUD/mcl_death_messages/locale/template.txt +++ b/mods/HUD/mcl_death_messages/locale/template.txt @@ -1,59 +1,58 @@ # textdomain: mcl_death_messages -@1 was fatally hit by an arrow.= -@1 has been killed with an arrow.= -@1 was shot by an arrow from @2.= -@1 was shot by an arrow from a skeleton.= -@1 was shot by an arrow from a stray.= -@1 was shot by an arrow from an illusioner.= -@1 was shot by an arrow.= -@1 forgot to breathe.= -@1 drowned.= -@1 ran out of oxygen.= -@1 was killed by @2.= -@1 was killed.= -@1 was killed by a mob.= -@1 was burned to death by a blaze's fireball.= -@1 was killed by a fireball from a blaze.= -@1 was burned by a fire charge.= -A ghast scared @1 to death.= -@1 has been fireballed by a ghast.= -@1 fell from a high cliff.= -@1 took fatal fall damage.= -@1 fell victim to gravity.= -@1 died.= -@1 was killed by a zombie.= -@1 was killed by a baby zombie.= -@1 was killed by a blaze.= -@1 was killed by a slime.= -@1 was killed by a witch.= -@1 was killed by a magma cube.= -@1 was killed by a wolf.= -@1 was killed by a cat.= -@1 was killed by an ocelot.= -@1 was killed by an ender dragon.= -@1 was killed by a wither.= -@1 was killed by an enderman.= -@1 was killed by an endermite.= -@1 was killed by a ghast.= -@1 was killed by an elder guardian.= -@1 was killed by a guardian.= -@1 was killed by an iron golem.= -@1 was killed by a polar_bear.= -@1 was killed by a killer bunny.= -@1 was killed by a shulker.= -@1 was killed by a silverfish.= -@1 was killed by a skeleton.= -@1 was killed by a stray.= -@1 was killed by a slime.= -@1 was killed by a spider.= -@1 was killed by a cave spider.= -@1 was killed by a vex.= -@1 was killed by an evoker.= -@1 was killed by an illusioner.= -@1 was killed by a vindicator.= -@1 was killed by a zombie villager.= -@1 was killed by a husk.= -@1 was killed by a baby husk.= -@1 was killed by a zombie pigman.= -@1 was killed by a baby zombie pigman.= -@1 was slain by @2.= +@1 went up in flames= +@1 walked into fire whilst fighting @2= +@1 was struck by lightning= +@1 was struck by lightning whilst fighting @2= +@1 burned to death= +@1 was burnt to a crisp whilst fighting @2= +@1 tried to swim in lava= +@1 tried to swim in lava to escape @2= +@1 discovered the floor was lava= +@1 walked into danger zone due to @2= +@1 suffocated in a wall= +@1 suffocated in a wall whilst fighting @2= +@1 drowned= +@1 drowned whilst trying to escape @2= +@1 starved to death= +@1 starved to death whilst fighting @2= +@1 was pricked to death= +@1 walked into a cactus whilst trying to escape @2= +@1 hit the ground too hard= +@1 hit the ground too hard whilst trying to escape @2= +@1 experienced kinetic energy= +@1 experienced kinetic energy whilst trying to escape @2= +@1 fell out of the world= +@1 didn't want to live in the same world as @2= +@1 died= +@1 died because of @2= +@1 was killed by magic= +@1 was killed by magic whilst trying to escape @2= +@1 was killed by @2 using magic= +@1 was killed by @2 using @3= +@1 was roasted in dragon breath= +@1 was roasted in dragon breath by @2= +@1 withered away= +@1 withered away whilst fighting @2= +@1 was killed by magic= +@1 was shot by a skull from @2= +@1 was squashed by a falling anvil= +@1 was squashed by a falling anvil whilst fighting @2= +@1 was squashed by a falling block= +@1 was squashed by a falling block whilst fighting @2= +@1 was slain by @2= +@1 was slain by @2 using @3= +@1 was slain by @2= +@1 was slain by @2 using @3= +@1 was shot by @2= +@1 was shot by @2 using @3= +@1 was fireballed by @2= +@1 was fireballed by @2 using @3= +@1 was killed trying to hurt @2= +@1 was killed by @3 trying to hurt @2= +@1 blew up= +@1 was blown up by @2= +@1 was blown up by @2 using @3= +@1 was squished too much= +@1 was squashed by @2= +@1 went off with a bang= +@1 went off with a bang due to a firework fired from @3 by @2= From b2407e407a4ee3ca26719b63ba4257c9f2387c86 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 17:30:15 +0200 Subject: [PATCH 40/43] Add mob descriptions --- mods/ENTITIES/mcl_mobs/api.lua | 1 + mods/ENTITIES/mobs_mc/bat.lua | 1 + mods/ENTITIES/mobs_mc/blaze.lua | 1 + mods/ENTITIES/mobs_mc/chicken.lua | 17 +-- mods/ENTITIES/mobs_mc/cow+mooshroom.lua | 35 +++--- mods/ENTITIES/mobs_mc/creeper.lua | 19 ++-- mods/ENTITIES/mobs_mc/ender_dragon.lua | 1 + mods/ENTITIES/mobs_mc/enderman.lua | 55 ++++----- mods/ENTITIES/mobs_mc/endermite.lua | 1 + mods/ENTITIES/mobs_mc/ghast.lua | 1 + mods/ENTITIES/mobs_mc/guardian.lua | 1 + mods/ENTITIES/mobs_mc/guardian_elder.lua | 1 + mods/ENTITIES/mobs_mc/horse.lua | 33 +++--- mods/ENTITIES/mobs_mc/iron_golem.lua | 1 + mods/ENTITIES/mobs_mc/llama.lua | 13 ++- mods/ENTITIES/mobs_mc/ocelot.lua | 20 ++-- mods/ENTITIES/mobs_mc/parrot.lua | 15 +-- mods/ENTITIES/mobs_mc/pig.lua | 17 +-- mods/ENTITIES/mobs_mc/polar_bear.lua | 3 +- mods/ENTITIES/mobs_mc/rabbit.lua | 18 +-- mods/ENTITIES/mobs_mc/sheep.lua | 13 ++- mods/ENTITIES/mobs_mc/shulker.lua | 19 ++-- mods/ENTITIES/mobs_mc/silverfish.lua | 1 + mods/ENTITIES/mobs_mc/skeleton+stray.lua | 2 + mods/ENTITIES/mobs_mc/skeleton_wither.lua | 1 + mods/ENTITIES/mobs_mc/slime+magma_cube.lua | 104 +++++++++--------- mods/ENTITIES/mobs_mc/snowman.lua | 1 + mods/ENTITIES/mobs_mc/spider.lua | 18 +-- mods/ENTITIES/mobs_mc/squid.lua | 1 + mods/ENTITIES/mobs_mc/vex.lua | 1 + mods/ENTITIES/mobs_mc/villager.lua | 1 + mods/ENTITIES/mobs_mc/villager_evoker.lua | 1 + mods/ENTITIES/mobs_mc/villager_illusioner.lua | 1 + mods/ENTITIES/mobs_mc/villager_vindicator.lua | 1 + mods/ENTITIES/mobs_mc/villager_zombie.lua | 1 + mods/ENTITIES/mobs_mc/witch.lua | 1 + mods/ENTITIES/mobs_mc/wither.lua | 1 + mods/ENTITIES/mobs_mc/wolf.lua | 15 +-- mods/ENTITIES/mobs_mc/zombie.lua | 4 + mods/ENTITIES/mobs_mc/zombiepig.lua | 34 +++--- 40 files changed, 264 insertions(+), 211 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 61077f688..25d11da16 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3771,6 +3771,7 @@ minetest.register_entity(name, { use_texture_alpha = def.use_texture_alpha, stepheight = def.stepheight or 0.6, name = name, + description = def.description, type = def.type, attack_type = def.attack_type, fly = def.fly, diff --git a/mods/ENTITIES/mobs_mc/bat.lua b/mods/ENTITIES/mobs_mc/bat.lua index 677b96aad..e9e1c1a16 100644 --- a/mods/ENTITIES/mobs_mc/bat.lua +++ b/mods/ENTITIES/mobs_mc/bat.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:bat", { + description = S("Bat"), type = "animal", spawn_class = "ambient", can_despawn = true, diff --git a/mods/ENTITIES/mobs_mc/blaze.lua b/mods/ENTITIES/mobs_mc/blaze.lua index 876237f19..5340b804e 100644 --- a/mods/ENTITIES/mobs_mc/blaze.lua +++ b/mods/ENTITIES/mobs_mc/blaze.lua @@ -11,6 +11,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:blaze", { + description = S("Blaze"), type = "monster", spawn_class = "hostile", hp_min = 20, diff --git a/mods/ENTITIES/mobs_mc/chicken.lua b/mods/ENTITIES/mobs_mc/chicken.lua index 246bf216a..615ec86e7 100644 --- a/mods/ENTITIES/mobs_mc/chicken.lua +++ b/mods/ENTITIES/mobs_mc/chicken.lua @@ -9,6 +9,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:chicken", { + description = S("Chicken"), type = "animal", spawn_class = "passive", @@ -95,14 +96,14 @@ mobs:register_mob("mobs_mc:chicken", { gain = 1.0, max_hear_distance = 16, }, true) - end, - + end, + }) --spawn mobs:spawn_specific( -"mobs_mc:chicken", -"overworld", +"mobs_mc:chicken", +"overworld", "ground", { "FlowerForest", @@ -122,10 +123,10 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -9, -minetest.LIGHT_MAX+1, -30, 17000, -3, +9, +minetest.LIGHT_MAX+1, +30, 17000, +3, mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) diff --git a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua index 48fcc8197..62e124463 100644 --- a/mods/ENTITIES/mobs_mc/cow+mooshroom.lua +++ b/mods/ENTITIES/mobs_mc/cow+mooshroom.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator("mobs_mc") local cow_def = { + description = S("Cow"), type = "animal", spawn_class = "passive", hp_min = 10, @@ -43,7 +44,7 @@ local cow_def = { stand_speed = 25, walk_speed = 40, run_speed = 60, stand_start = 0, stand_end = 0, walk_start = 0, - walk_end = 40, run_start = 0, + walk_end = 40, run_start = 0, run_end = 40, }, follow = mobs_mc.follow.cow, @@ -81,7 +82,7 @@ mobs:register_mob("mobs_mc:cow", cow_def) -- Mooshroom local mooshroom_def = table.copy(cow_def) - +mooshroom_def.description = S("Mooshroom") mooshroom_def.mesh = "mobs_mc_cow.b3d" mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } } mooshroom_def.on_rightclick = function(self, clicker) @@ -147,7 +148,7 @@ mobs:register_mob("mobs_mc:mooshroom", mooshroom_def) -- Spawning mobs:spawn_specific( "mobs_mc:cow", -"overworld", +"overworld", "ground", { "FlowerForest", @@ -167,30 +168,30 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -9, -minetest.LIGHT_MAX+1, -30, -17000, -10, -mobs_mc.spawn_height.water, +9, +minetest.LIGHT_MAX+1, +30, +17000, +10, +mobs_mc.spawn_height.water, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific( -"mobs_mc:mooshroom", -"overworld", +"mobs_mc:mooshroom", +"overworld", "ground", { "MushroomIslandShore", "MushroomIsland" }, -9, -minetest.LIGHT_MAX+1, -30, -17000, -5, -mobs_mc.spawn_height.overworld_min, +9, +minetest.LIGHT_MAX+1, +30, +17000, +5, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn egg diff --git a/mods/ENTITIES/mobs_mc/creeper.lua b/mods/ENTITIES/mobs_mc/creeper.lua index 0c884d569..827d08aab 100644 --- a/mods/ENTITIES/mobs_mc/creeper.lua +++ b/mods/ENTITIES/mobs_mc/creeper.lua @@ -130,6 +130,7 @@ mobs:register_mob("mobs_mc:creeper", { }) mobs:register_mob("mobs_mc:creeper_charged", { + description = S("Creeper"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -142,7 +143,7 @@ mobs:register_mob("mobs_mc:creeper_charged", { mesh = "mobs_mc_creeper.b3d", --BOOM - + textures = { {"mobs_mc_creeper.png", "mobs_mc_creeper_charge.png"}, @@ -254,8 +255,8 @@ mobs:register_mob("mobs_mc:creeper_charged", { }) mobs:spawn_specific( -"mobs_mc:creeper", -"overworld", +"mobs_mc:creeper", +"overworld", "ground", { "Mesa", @@ -398,12 +399,12 @@ mobs:spawn_specific( "ExtremeHillsM_underground", "JungleEdgeM_underground", }, -0, -7, -20, -16500, -2, -mobs_mc.spawn_height.overworld_min, +0, +7, +20, +16500, +2, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index a6f404275..8b0b1977b 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:enderdragon", { + description = S("Ender Dragon"), type = "monster", spawn_class = "hostile", pathfinding = 1, diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 9c47e98fc..7c55b34d6 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -190,6 +190,7 @@ end local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false mobs:register_mob("mobs_mc:enderman", { + description = S("Enderman"), type = "monster", spawn_class = "passive", passive = true, @@ -330,7 +331,7 @@ mobs:register_mob("mobs_mc:enderman", { end -- Check to see if people are near by enough to look at us. for _,obj in pairs(minetest.get_connected_players()) do - + --check if they are within radius local player_pos = obj:get_pos() if player_pos then -- prevent crashing in 1 in a million scenario @@ -355,7 +356,7 @@ mobs:register_mob("mobs_mc:enderman", { local ender_eye_pos = vector.new(enderpos.x, enderpos.y + 2.75, enderpos.z) local eye_distance_from_player = vector.distance(ender_eye_pos, look_pos) look_pos = vector.add(look_pos, vector.multiply(look_dir, eye_distance_from_player)) - + --if looking in general head position, turn hostile if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then self.provoked = "staring" @@ -364,7 +365,7 @@ mobs:register_mob("mobs_mc:enderman", { else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez if self.provoked == "staring" then self.provoked = "broke_contact" - end + end end end @@ -562,23 +563,23 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn mobs:spawn_specific( -"mobs_mc:enderman", -"end", +"mobs_mc:enderman", +"end", "ground", { "End" }, -0, -minetest.LIGHT_MAX+1, -30, -3000, -12, -mobs_mc.spawn_height.end_min, +0, +minetest.LIGHT_MAX+1, +30, +3000, +12, +mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn mobs:spawn_specific( -"mobs_mc:enderman", -"overworld", +"mobs_mc:enderman", +"overworld", "ground", { "Mesa", @@ -721,28 +722,28 @@ mobs:spawn_specific( "ExtremeHillsM_underground", "JungleEdgeM_underground", }, -0, -7, -30, -19000, -2, -mobs_mc.spawn_height.overworld_min, +0, +7, +30, +19000, +2, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) mobs:spawn_specific( -"mobs_mc:enderman", -"nether", +"mobs_mc:enderman", +"nether", "ground", { "Nether" }, -0, -7, -30, -27500, -4, -mobs_mc.spawn_height.nether_min, +0, +7, +30, +27500, +4, +mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/endermite.lua b/mods/ENTITIES/mobs_mc/endermite.lua index da3922a10..2bffa8304 100644 --- a/mods/ENTITIES/mobs_mc/endermite.lua +++ b/mods/ENTITIES/mobs_mc/endermite.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:endermite", { + description = S("Endermite"), type = "monster", spawn_class = "hostile", passive = false, diff --git a/mods/ENTITIES/mobs_mc/ghast.lua b/mods/ENTITIES/mobs_mc/ghast.lua index 48d71b45e..1d7179162 100644 --- a/mods/ENTITIES/mobs_mc/ghast.lua +++ b/mods/ENTITIES/mobs_mc/ghast.lua @@ -11,6 +11,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:ghast", { + description = S("Ghast"), type = "monster", spawn_class = "hostile", pathfinding = 1, diff --git a/mods/ENTITIES/mobs_mc/guardian.lua b/mods/ENTITIES/mobs_mc/guardian.lua index 13c857ea3..06a2ba2e2 100644 --- a/mods/ENTITIES/mobs_mc/guardian.lua +++ b/mods/ENTITIES/mobs_mc/guardian.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:guardian", { + description = S("Guardian"), type = "monster", spawn_class = "hostile", hp_min = 30, diff --git a/mods/ENTITIES/mobs_mc/guardian_elder.lua b/mods/ENTITIES/mobs_mc/guardian_elder.lua index 089f6e38f..5b8150dd4 100644 --- a/mods/ENTITIES/mobs_mc/guardian_elder.lua +++ b/mods/ENTITIES/mobs_mc/guardian_elder.lua @@ -7,6 +7,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:guardian_elder", { + description = S("Elder Guardian"), type = "monster", spawn_class = "hostile", hp_min = 80, diff --git a/mods/ENTITIES/mobs_mc/horse.lua b/mods/ENTITIES/mobs_mc/horse.lua index 938a6b6ac..ac631f205 100644 --- a/mods/ENTITIES/mobs_mc/horse.lua +++ b/mods/ENTITIES/mobs_mc/horse.lua @@ -83,6 +83,7 @@ end -- Horse local horse = { + description = S("Horse"), type = "animal", spawn_class = "passive", visual = "mesh", @@ -418,6 +419,7 @@ mobs:register_mob("mobs_mc:horse", horse) -- Skeleton horse local skeleton_horse = table.copy(horse) +skeleton_horse.description = S("Skeleton Horse") skeleton_horse.breath_max = -1 skeleton_horse.armor = {undead = 100, fleshy = 100} skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}} @@ -440,6 +442,7 @@ mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse) -- Zombie horse local zombie_horse = table.copy(horse) +zombie_horse.description = S("Zombie Horse") zombie_horse.breath_max = -1 zombie_horse.armor = {undead = 100, fleshy = 100} zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}} @@ -464,6 +467,7 @@ mobs:register_mob("mobs_mc:zombie_horse", zombie_horse) -- Donkey local d = 0.86 -- donkey scale local donkey = table.copy(horse) +donkey.description = S("Donkey") donkey.textures = {{"blank.png", "mobs_mc_donkey.png", "blank.png"}} donkey.animation = { speed_normal = 25, @@ -494,6 +498,7 @@ mobs:register_mob("mobs_mc:donkey", donkey) -- Mule local m = 0.94 local mule = table.copy(donkey) +mule.description = S("Mule") mule.textures = {{"blank.png", "mobs_mc_mule.png", "blank.png"}} mule.visual_size = { x=horse.visual_size.x*m, y=horse.visual_size.y*m } mule.sounds = table.copy(donkey.sounds) @@ -532,18 +537,18 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -4, -mobs_mc.spawn_height.water+3, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:spawn_specific( -"mobs_mc:donkey", -"overworld", +"mobs_mc:donkey", +"overworld", "ground", { "Mesa", @@ -553,12 +558,12 @@ mobs:spawn_specific( "MesaPlateauF_grasstop", "MesaBryce", }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -4, -mobs_mc.spawn_height.water+3, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 2ccee2d0a..0d3e74645 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -12,6 +12,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:iron_golem", { + description = S("Iron Golem"), type = "npc", spawn_class = "passive", passive = true, diff --git a/mods/ENTITIES/mobs_mc/llama.lua b/mods/ENTITIES/mobs_mc/llama.lua index 8ff82b502..655cddfb6 100644 --- a/mods/ENTITIES/mobs_mc/llama.lua +++ b/mods/ENTITIES/mobs_mc/llama.lua @@ -25,6 +25,7 @@ local carpets = { } mobs:register_mob("mobs_mc:llama", { + description = S("Llama"), type = "animal", spawn_class = "passive", hp_min = 15, @@ -229,12 +230,12 @@ mobs:spawn_specific( "MesaPlateauF_grasstop", "MesaBryce", }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -5, -mobs_mc.spawn_height.water+15, +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/ocelot.lua b/mods/ENTITIES/mobs_mc/ocelot.lua index f3c8c87ae..5a3f135a1 100644 --- a/mods/ENTITIES/mobs_mc/ocelot.lua +++ b/mods/ENTITIES/mobs_mc/ocelot.lua @@ -27,6 +27,7 @@ end -- Ocelot local ocelot = { + description = S("Ocelot"), type = "animal", spawn_class = "passive", can_despawn = true, @@ -102,6 +103,7 @@ mobs:register_mob("mobs_mc:ocelot", ocelot) -- Cat local cat = table.copy(ocelot) +cat.description = S("Cat") cat.textures = {{"mobs_mc_cat_black.png"}, {"mobs_mc_cat_red.png"}, {"mobs_mc_cat_siamese.png"}} cat.can_despawn = false cat.owner = "" @@ -154,8 +156,8 @@ local base_spawn_chance = 5000 -- Spawn ocelot --they get the same as the llama because I'm trying to rework so much of this code right now -j4i mobs:spawn_specific( -"mobs_mc:ocelot", -"overworld", +"mobs_mc:ocelot", +"overworld", "ground", { "Jungle", @@ -163,12 +165,12 @@ mobs:spawn_specific( "JungleM", "JungleEdge", }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -5, -mobs_mc.spawn_height.water+15, +0, +minetest.LIGHT_MAX+1, +30, +15000, +5, +mobs_mc.spawn_height.water+15, mobs_mc.spawn_height.overworld_max) --[[ mobs:spawn({ @@ -183,7 +185,7 @@ mobs:spawn({ max_height = mobs_mc.spawn_height.overworld_max, on_spawn = function(self, pos) Note: Minecraft has a 1/3 spawn failure rate. - In this mod it is emulated by reducing the spawn rate accordingly (see above). + In this mod it is emulated by reducing the spawn rate accordingly (see above). -- 1/7 chance to spawn 2 ocelot kittens if pr:next(1,7) == 1 then diff --git a/mods/ENTITIES/mobs_mc/parrot.lua b/mods/ENTITIES/mobs_mc/parrot.lua index 5efcb191b..c04ea77c6 100644 --- a/mods/ENTITIES/mobs_mc/parrot.lua +++ b/mods/ENTITIES/mobs_mc/parrot.lua @@ -12,6 +12,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:parrot", { + description = S("Parrot"), type = "npc", spawn_class = "passive", pathfinding = 1, @@ -93,7 +94,7 @@ mobs:register_mob("mobs_mc:parrot", { -- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i mobs:spawn_specific( "mobs_mc:parrot", -"overworld", +"overworld", "ground", { "Jungle", @@ -101,12 +102,12 @@ mobs:spawn_specific( "JungleM", "JungleEdge", }, -0, -minetest.LIGHT_MAX+1, -7, -30000, -1, -mobs_mc.spawn_height.water+7, +0, +minetest.LIGHT_MAX+1, +7, +30000, +1, +mobs_mc.spawn_height.water+7, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/pig.lua b/mods/ENTITIES/mobs_mc/pig.lua index b7cdf1afe..b7d919cff 100644 --- a/mods/ENTITIES/mobs_mc/pig.lua +++ b/mods/ENTITIES/mobs_mc/pig.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:pig", { + description = S("Pig"), type = "animal", spawn_class = "passive", runaway = true, @@ -183,8 +184,8 @@ mobs:register_mob("mobs_mc:pig", { }) mobs:spawn_specific( -"mobs_mc:pig", -"overworld", +"mobs_mc:pig", +"overworld", "ground", { "FlowerForest", @@ -204,12 +205,12 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -9, -minetest.LIGHT_MAX+1, -30, -15000, -8, -mobs_mc.spawn_height.overworld_min, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/polar_bear.lua b/mods/ENTITIES/mobs_mc/polar_bear.lua index 5d2853f6d..98268961b 100644 --- a/mods/ENTITIES/mobs_mc/polar_bear.lua +++ b/mods/ENTITIES/mobs_mc/polar_bear.lua @@ -8,6 +8,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:polar_bear", { + description = S("Polar Bear"), type = "animal", spawn_class = "passive", runaway = false, @@ -37,7 +38,7 @@ mobs:register_mob("mobs_mc:polar_bear", { chance = 2, min = 0, max = 2, - looting = "common",}, + looting = "common",}, -- 1/4 to drop raw salmon {name = mobs_mc.items.salmon_raw, chance = 4, diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index 74bdffcd8..6b47fec70 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -3,6 +3,7 @@ local S = minetest.get_translator("mobs_mc") local rabbit = { + description = S("Rabbit"), type = "animal", spawn_class = "passive", passive = true, @@ -83,6 +84,7 @@ mobs:register_mob("mobs_mc:rabbit", rabbit) -- The killer bunny (Only with spawn egg) local killer_bunny = table.copy(rabbit) +killer_bunny.description = S("Killer Bunny") killer_bunny.type = "monster" killer_bunny.spawn_class = "hostile" killer_bunny.attack_type = "dogfight" @@ -110,8 +112,8 @@ mobs:register_mob("mobs_mc:killer_bunny", killer_bunny) -- Different skins depending on spawn location <- we'll get to this when the spawning algorithm is fleshed out mobs:spawn_specific( -"mobs_mc:rabbit", -"overworld", +"mobs_mc:rabbit", +"overworld", "ground", { "FlowerForest", @@ -131,12 +133,12 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -9, -minetest.LIGHT_MAX+1, -30, -15000, -8, -mobs_mc.spawn_height.overworld_min, +9, +minetest.LIGHT_MAX+1, +30, +15000, +8, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) --[[ diff --git a/mods/ENTITIES/mobs_mc/sheep.lua b/mods/ENTITIES/mobs_mc/sheep.lua index d82df8cf9..9ddc0adee 100644 --- a/mods/ENTITIES/mobs_mc/sheep.lua +++ b/mods/ENTITIES/mobs_mc/sheep.lua @@ -56,6 +56,7 @@ local gotten_texture = { "blank.png", "mobs_mc_sheep.png" } --mcsheep mobs:register_mob("mobs_mc:sheep", { + description = S("Sheep"), type = "animal", spawn_class = "passive", hp_min = 8, @@ -325,12 +326,12 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -3, -mobs_mc.spawn_height.overworld_min, +0, +minetest.LIGHT_MAX+1, +30, +15000, +3, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/shulker.lua b/mods/ENTITIES/mobs_mc/shulker.lua index 8000d0937..0d5ad880a 100644 --- a/mods/ENTITIES/mobs_mc/shulker.lua +++ b/mods/ENTITIES/mobs_mc/shulker.lua @@ -10,8 +10,9 @@ local S = minetest.get_translator("mobs_mc") --################### -- animation 45-80 is transition between passive and attack stance - + mobs:register_mob("mobs_mc:shulker", { + description = S("Shulker"), type = "monster", spawn_class = "hostile", attack_type = "shoot", @@ -82,16 +83,16 @@ mobs:register_arrow("mobs_mc:shulkerbullet", { mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0) mobs:spawn_specific( -"mobs_mc:shulker", -"end", +"mobs_mc:shulker", +"end", "ground", { "End" }, -0, -minetest.LIGHT_MAX+1, -30, -5000, -2, -mobs_mc.spawn_height.end_min, +0, +minetest.LIGHT_MAX+1, +30, +5000, +2, +mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) diff --git a/mods/ENTITIES/mobs_mc/silverfish.lua b/mods/ENTITIES/mobs_mc/silverfish.lua index 433211503..5af3c8aa0 100644 --- a/mods/ENTITIES/mobs_mc/silverfish.lua +++ b/mods/ENTITIES/mobs_mc/silverfish.lua @@ -5,6 +5,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:silverfish", { + description = S("Silverfish"), type = "monster", spawn_class = "hostile", passive = false, diff --git a/mods/ENTITIES/mobs_mc/skeleton+stray.lua b/mods/ENTITIES/mobs_mc/skeleton+stray.lua index 05b829bcd..61e1c6eb2 100644 --- a/mods/ENTITIES/mobs_mc/skeleton+stray.lua +++ b/mods/ENTITIES/mobs_mc/skeleton+stray.lua @@ -13,6 +13,7 @@ local mod_bows = minetest.get_modpath("mcl_bows") ~= nil local skeleton = { + description = S("Skeleton"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -109,6 +110,7 @@ mobs:register_mob("mobs_mc:skeleton", skeleton) --################### local stray = table.copy(skeleton) +stray.description = S("Stray") stray.mesh = "mobs_mc_skeleton.b3d" stray.textures = { { diff --git a/mods/ENTITIES/mobs_mc/skeleton_wither.lua b/mods/ENTITIES/mobs_mc/skeleton_wither.lua index c089850f4..1c0bdbea1 100644 --- a/mods/ENTITIES/mobs_mc/skeleton_wither.lua +++ b/mods/ENTITIES/mobs_mc/skeleton_wither.lua @@ -10,6 +10,7 @@ local S = minetest.get_translator("mobs_mc") --################### mobs:register_mob("mobs_mc:witherskeleton", { + description = S("Wither Skeleton"), type = "monster", spawn_class = "hostile", hp_min = 20, diff --git a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua index 6c8000a50..28621ee6f 100644 --- a/mods/ENTITIES/mobs_mc/slime+magma_cube.lua +++ b/mods/ENTITIES/mobs_mc/slime+magma_cube.lua @@ -56,6 +56,7 @@ end -- Slime local slime_big = { + description = S("Slime"), type = "monster", spawn_class = "hostile", pathfinding = 1, @@ -158,8 +159,8 @@ local smin = mobs_mc.spawn_height.overworld_min local smax = mobs_mc.spawn_height.water - 23 mobs:spawn_specific( -"mobs_mc:slime_tiny", -"overworld", +"mobs_mc:slime_tiny", +"overworld", "ground", { "FlowerForest_underground", @@ -193,17 +194,17 @@ mobs:spawn_specific( "ExtremeHillsM_underground", "JungleEdgeM_underground", }, -0, -minetest.LIGHT_MAX+1, -30, -12000, -4, -smin, +0, +minetest.LIGHT_MAX+1, +30, +12000, +4, +smin, smax) mobs:spawn_specific( -"mobs_mc:slime_small", -"overworld", +"mobs_mc:slime_small", +"overworld", "ground", { "FlowerForest_underground", @@ -236,19 +237,19 @@ mobs:spawn_specific( "JungleM_underground", "ExtremeHillsM_underground", "JungleEdgeM_underground", -}, -0, -minetest.LIGHT_MAX+1, -30, -8500, -4, -smin, +}, +0, +minetest.LIGHT_MAX+1, +30, +8500, +4, +smin, smax) mobs:spawn_specific( -"mobs_mc:slime_big", -"overworld", -"ground", +"mobs_mc:slime_big", +"overworld", +"ground", { "FlowerForest_underground", "JungleEdge_underground", @@ -281,16 +282,17 @@ mobs:spawn_specific( "ExtremeHillsM_underground", "JungleEdgeM_underground", }, -0, -minetest.LIGHT_MAX+1, -30, -10000, -4, -smin, +0, +minetest.LIGHT_MAX+1, +30, +10000, +4, +smin, smax) -- Magma cube local magma_cube_big = { + description = S("Magma Cube"), type = "monster", spawn_class = "hostile", hp_min = 16, @@ -401,49 +403,49 @@ local mmin = mobs_mc.spawn_height.nether_min local mmax = mobs_mc.spawn_height.nether_max mobs:spawn_specific( -"mobs_mc:magma_cube_tiny", -"nether", +"mobs_mc:magma_cube_tiny", +"nether", "ground", { "Nether" }, -0, -minetest.LIGHT_MAX+1, -30, -15000, -4, -mmin, +0, +minetest.LIGHT_MAX+1, +30, +15000, +4, +mmin, mmax) mobs:spawn_specific( -"mobs_mc:magma_cube_small", -"nether", +"mobs_mc:magma_cube_small", +"nether", "ground", { "Nether" }, -0, -minetest.LIGHT_MAX+1, -30, -15500, -4, -mmin, +0, +minetest.LIGHT_MAX+1, +30, +15500, +4, +mmin, mmax) mobs:spawn_specific( -"mobs_mc:magma_cube_big", -"nether", +"mobs_mc:magma_cube_big", +"nether", "ground", { "Nether" -}, -0, -minetest.LIGHT_MAX+1, -30, -16000, -4, -mmin, +}, +0, +minetest.LIGHT_MAX+1, +30, +16000, +4, +mmin, mmax) --mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax) diff --git a/mods/ENTITIES/mobs_mc/snowman.lua b/mods/ENTITIES/mobs_mc/snowman.lua index 1ee88b362..93f91c330 100644 --- a/mods/ENTITIES/mobs_mc/snowman.lua +++ b/mods/ENTITIES/mobs_mc/snowman.lua @@ -21,6 +21,7 @@ local gotten_texture = { } mobs:register_mob("mobs_mc:snowman", { + description = S("Snow Golem"), type = "npc", spawn_class = "passive", passive = true, diff --git a/mods/ENTITIES/mobs_mc/spider.lua b/mods/ENTITIES/mobs_mc/spider.lua index bb5e29eb1..c1cb5be4b 100644 --- a/mods/ENTITIES/mobs_mc/spider.lua +++ b/mods/ENTITIES/mobs_mc/spider.lua @@ -13,6 +13,7 @@ local S = minetest.get_translator("mobs_mc") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture) local spider = { + description = S("Spider"), type = "monster", spawn_class = "hostile", passive = false, @@ -72,6 +73,7 @@ mobs:register_mob("mobs_mc:spider", spider) -- Cave spider local cave_spider = table.copy(spider) +cave_spider.description = S("Cave Spider") cave_spider.textures = { {"mobs_mc_cave_spider.png^(mobs_mc_spider_eyes.png^[makealpha:0,0,0)"} } -- TODO: Poison damage -- TODO: Revert damage to 2 @@ -88,8 +90,8 @@ mobs:register_mob("mobs_mc:cave_spider", cave_spider) mobs:spawn_specific( -"mobs_mc:spider", -"overworld", +"mobs_mc:spider", +"overworld", "ground", { "Mesa", @@ -232,12 +234,12 @@ mobs:spawn_specific( "ExtremeHillsM_underground", "JungleEdgeM_underground", }, -0, -7, -30, -17000, -2, -mobs_mc.spawn_height.overworld_min, +0, +7, +30, +17000, +2, +mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- spawn eggs diff --git a/mods/ENTITIES/mobs_mc/squid.lua b/mods/ENTITIES/mobs_mc/squid.lua index cf794ea5b..0c425bb51 100644 --- a/mods/ENTITIES/mobs_mc/squid.lua +++ b/mods/ENTITIES/mobs_mc/squid.lua @@ -7,6 +7,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:squid", { + description = S("Squid"), type = "animal", spawn_class = "water", can_despawn = true, diff --git a/mods/ENTITIES/mobs_mc/vex.lua b/mods/ENTITIES/mobs_mc/vex.lua index cccdebe7a..a72827d5d 100644 --- a/mods/ENTITIES/mobs_mc/vex.lua +++ b/mods/ENTITIES/mobs_mc/vex.lua @@ -10,6 +10,7 @@ local S = minetest.get_translator("mobs_mc") --################### mobs:register_mob("mobs_mc:vex", { + description = S("Vex"), type = "monster", spawn_class = "hostile", pathfinding = 1, diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index ab79edfec..db9cf3b19 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -927,6 +927,7 @@ end) --[=======[ MOB REGISTRATION AND SPAWNING ]=======] mobs:register_mob("mobs_mc:villager", { + description = S("Villager"), type = "npc", spawn_class = "passive", hp_min = 20, diff --git a/mods/ENTITIES/mobs_mc/villager_evoker.lua b/mods/ENTITIES/mobs_mc/villager_evoker.lua index abe0e9ca2..04c95b88f 100644 --- a/mods/ENTITIES/mobs_mc/villager_evoker.lua +++ b/mods/ENTITIES/mobs_mc/villager_evoker.lua @@ -12,6 +12,7 @@ local S = minetest.get_translator("mobs_mc") local pr = PseudoRandom(os.time()*666) mobs:register_mob("mobs_mc:evoker", { + description = S("Evoker"), type = "monster", spawn_class = "hostile", physical = true, diff --git a/mods/ENTITIES/mobs_mc/villager_illusioner.lua b/mods/ENTITIES/mobs_mc/villager_illusioner.lua index 0bbe2a5f6..496f08fc6 100644 --- a/mods/ENTITIES/mobs_mc/villager_illusioner.lua +++ b/mods/ENTITIES/mobs_mc/villager_illusioner.lua @@ -7,6 +7,7 @@ local S = minetest.get_translator("mobs_mc") local mod_bows = minetest.get_modpath("mcl_bows") ~= nil mobs:register_mob("mobs_mc:illusioner", { + description = S("Illusioner"), type = "monster", spawn_class = "hostile", attack_type = "shoot", diff --git a/mods/ENTITIES/mobs_mc/villager_vindicator.lua b/mods/ENTITIES/mobs_mc/villager_vindicator.lua index 56b295066..276f80011 100644 --- a/mods/ENTITIES/mobs_mc/villager_vindicator.lua +++ b/mods/ENTITIES/mobs_mc/villager_vindicator.lua @@ -11,6 +11,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:vindicator", { + description = S("Vindicator"), type = "monster", spawn_class = "hostile", physical = false, diff --git a/mods/ENTITIES/mobs_mc/villager_zombie.lua b/mods/ENTITIES/mobs_mc/villager_zombie.lua index b90823629..1948b693d 100644 --- a/mods/ENTITIES/mobs_mc/villager_zombie.lua +++ b/mods/ENTITIES/mobs_mc/villager_zombie.lua @@ -26,6 +26,7 @@ local professions = { } mobs:register_mob("mobs_mc:villager_zombie", { + description = S("Zombie Villager"), type = "monster", spawn_class = "hostile", hp_min = 20, diff --git a/mods/ENTITIES/mobs_mc/witch.lua b/mods/ENTITIES/mobs_mc/witch.lua index f9f9b8d1f..8ebe71fc0 100644 --- a/mods/ENTITIES/mobs_mc/witch.lua +++ b/mods/ENTITIES/mobs_mc/witch.lua @@ -13,6 +13,7 @@ local S = minetest.get_translator("mobs_mc") mobs:register_mob("mobs_mc:witch", { + description = S("Witch"), type = "monster", spawn_class = "hostile", hp_min = 26, diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index 2d53cc547..72459a354 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -10,6 +10,7 @@ local S = minetest.get_translator("mobs_mc") --################### mobs:register_mob("mobs_mc:wither", { + description = S("Wither"), type = "monster", spawn_class = "hostile", hp_max = 300, diff --git a/mods/ENTITIES/mobs_mc/wolf.lua b/mods/ENTITIES/mobs_mc/wolf.lua index b1c077d46..7f14ac6b0 100644 --- a/mods/ENTITIES/mobs_mc/wolf.lua +++ b/mods/ENTITIES/mobs_mc/wolf.lua @@ -19,6 +19,7 @@ end -- Wolf local wolf = { + description = S("Wolf"), type = "animal", spawn_class = "passive", can_despawn = true, @@ -138,7 +139,7 @@ dog.owner = "" -- TODO: Start sitting by default dog.order = "roam" dog.owner_loyal = true -dog.follow_velocity = 3.2 +dog.follow_velocity = 3.2 -- Automatically teleport dog to owner dog.do_custom = mobs_mc.make_owner_teleport_function(12) dog.follow = mobs_mc.follow.dog @@ -254,12 +255,12 @@ mobs:spawn_specific( "ExtremeHillsM", "BirchForestM", }, -0, -minetest.LIGHT_MAX+1, -30, -9000, -7, -mobs_mc.spawn_height.water+3, +0, +minetest.LIGHT_MAX+1, +30, +9000, +7, +mobs_mc.spawn_height.water+3, mobs_mc.spawn_height.overworld_max) mobs:register_egg("mobs_mc:wolf", S("Wolf"), "mobs_mc_spawn_icon_wolf.png", 0) diff --git a/mods/ENTITIES/mobs_mc/zombie.lua b/mods/ENTITIES/mobs_mc/zombie.lua index 1be47848b..4ae5796b3 100644 --- a/mods/ENTITIES/mobs_mc/zombie.lua +++ b/mods/ENTITIES/mobs_mc/zombie.lua @@ -46,6 +46,7 @@ table.insert(drops_zombie, { }) local zombie = { + description = S("Zombie"), type = "monster", spawn_class = "hostile", hp_min = 20, @@ -102,6 +103,7 @@ mobs:register_mob("mobs_mc:zombie", zombie) -- A smaller and more dangerous variant of the zombie local baby_zombie = table.copy(zombie) +baby_zombie.description = S("Baby Zombie") baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} baby_zombie.xp_min = 12 baby_zombie.xp_max = 12 @@ -115,6 +117,7 @@ mobs:register_mob("mobs_mc:baby_zombie", baby_zombie) -- Husk. -- Desert variant of the zombie local husk = table.copy(zombie) +husk.description = S("Husk") husk.textures = { { "mobs_mc_empty.png", -- armor @@ -132,6 +135,7 @@ mobs:register_mob("mobs_mc:husk", husk) -- Baby husk. -- A smaller and more dangerous variant of the husk local baby_husk = table.copy(husk) +baby_husk.description = S("Baby Husk") baby_husk.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} baby_husk.xp_min = 12 baby_husk.xp_max = 12 diff --git a/mods/ENTITIES/mobs_mc/zombiepig.lua b/mods/ENTITIES/mobs_mc/zombiepig.lua index ebd8ce485..1ea4197c1 100644 --- a/mods/ENTITIES/mobs_mc/zombiepig.lua +++ b/mods/ENTITIES/mobs_mc/zombiepig.lua @@ -11,6 +11,7 @@ local S = minetest.get_translator("mobs_mc") local pigman = { + description = S("Zombie Pigman"), -- type="animal", passive=false: This combination is needed for a neutral mob which becomes hostile, if attacked type = "animal", passive = false, @@ -94,6 +95,7 @@ mobs:register_mob("mobs_mc:pigman", pigman) -- A smaller and more dangerous variant of the pigman local baby_pigman = table.copy(pigman) +baby_pigman.description = S("Baby Zombie Pigman") baby_pigman.collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.94, 0.25} baby_pigman.xp_min = 13 baby_pigman.xp_max = 13 @@ -112,33 +114,33 @@ mobs:register_mob("mobs_mc:baby_pigman", baby_pigman) -- Regular spawning in the Nether mobs:spawn_specific( -"mobs_mc:pigman", -"nether", +"mobs_mc:pigman", +"nether", "ground", { "Nether" }, -0, +0, minetest.LIGHT_MAX+1, -30, -6000, -3, -mobs_mc.spawn_height.nether_min, +30, +6000, +3, +mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Baby zombie is 20 times less likely than regular zombies mobs:spawn_specific( -"mobs_mc:baby_pigman", -"nether", +"mobs_mc:baby_pigman", +"nether", "ground", { "Nether" -}, -0, -minetest.LIGHT_MAX+1, -30, -100000, -4, -mobs_mc.spawn_height.nether_min, +}, +0, +minetest.LIGHT_MAX+1, +30, +100000, +4, +mobs_mc.spawn_height.nether_min, mobs_mc.spawn_height.nether_max) -- Spawning in Nether portals in the Overworld From 97e69e04aacd6a1f93e585d7ff20be6babed435a Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 17:49:27 +0200 Subject: [PATCH 41/43] Implement assist death messages --- mods/HUD/mcl_death_messages/init.lua | 105 +++++++++++---------------- 1 file changed, 43 insertions(+), 62 deletions(-) diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index 874af7754..9087c41e9 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -1,56 +1,57 @@ local S = minetest.get_translator("mcl_death_messages") mcl_death_messages = { + assist = {}, messages = { in_fire = { _translator = S, plain = "@1 went up in flames", - escape = "@1 walked into fire whilst fighting @2", + assist = "@1 walked into fire whilst fighting @2", }, lightning_bolt = { _translator = S, plain = "@1 was struck by lightning", - escape = "@1 was struck by lightning whilst fighting @2", + assist = "@1 was struck by lightning whilst fighting @2", }, on_fire = { _translator = S, plain = "@1 burned to death", - escape = "@1 was burnt to a crisp whilst fighting @2", + assist = "@1 was burnt to a crisp whilst fighting @2", }, lava = { _translator = S, plain = "@1 tried to swim in lava", - escape = "@1 tried to swim in lava to escape @2" + assist = "@1 tried to swim in lava to escape @2" }, hot_floor = { _translator = S, plain = "@1 discovered the floor was lava", - escape = "@1 walked into danger zone due to @2", + assist = "@1 walked into danger zone due to @2", }, in_wall = { _translator = S, plain = "@1 suffocated in a wall", - escape = "@1 suffocated in a wall whilst fighting @2", + assist = "@1 suffocated in a wall whilst fighting @2", }, drown = { _translator = S, plain = "@1 drowned", - escape = "@1 drowned whilst trying to escape @2", + assist = "@1 drowned whilst trying to escape @2", }, starve = { _translator = S, plain = "@1 starved to death", - escape = "@1 starved to death whilst fighting @2", + assist = "@1 starved to death whilst fighting @2", }, cactus = { _translator = S, plain = "@1 was pricked to death", - escape = "@1 walked into a cactus whilst trying to escape @2", + assist = "@1 walked into a cactus whilst trying to escape @2", }, fall = { _translator = S, plain = "@1 hit the ground too hard", - escape = "@1 hit the ground too hard whilst trying to escape @2", + assist = "@1 hit the ground too hard whilst trying to escape @2", -- "@1 fell from a high place" -- for fall distance > 5 blocks -- "@1 fell while climbing" -- "@1 fell off some twisting vines" @@ -62,22 +63,22 @@ mcl_death_messages = { fly_into_wall = { _translator = S, plain = "@1 experienced kinetic energy", - escape = "@1 experienced kinetic energy whilst trying to escape @2", + assist = "@1 experienced kinetic energy whilst trying to escape @2", }, out_of_world = { _translator = S, plain = "@1 fell out of the world", - escape = "@1 didn't want to live in the same world as @2", + assist = "@1 didn't want to live in the same world as @2", }, generic = { _translator = S, plain = "@1 died", - escape = "@1 died because of @2", + assist = "@1 died because of @2", }, magic = { _translator = S, plain = "@1 was killed by magic", - escape = "@1 was killed by magic whilst trying to escape @2", + assist = "@1 was killed by magic whilst trying to escape @2", killer = "@1 was killed by @2 using magic", item = "@1 was killed by @2 using @3", }, @@ -104,7 +105,7 @@ mcl_death_messages = { falling_node = { _translator = S, plain = "@1 was squashed by a falling block", - escape = "@1 was squashed by a falling block whilst fighting @2", + assist = "@1 was squashed by a falling block whilst fighting @2", }, mob = { _translator = S, @@ -141,7 +142,7 @@ mcl_death_messages = { cramming = { _translator = S, plain = "@1 was squished too much", - escape = "@1 was squashed by @2", -- surprisingly "escape" is actually the correct subtype + assist = "@1 was squashed by @2", -- surprisingly "escape" is actually the correct subtype }, fireworks = { _translator = S, @@ -151,49 +152,6 @@ mcl_death_messages = { -- Missing snowballs: The Minecraft wiki mentions them but the MC source code does not. }, } ---[[ -local mobkills = { - ["mobs_mc:zombie"] = N("@1 was slain by Zombie."), - ["mobs_mc:baby_zombie"] = N("@1 was slain by Baby Zombie."), - ["mobs_mc:blaze"] = N("@1 was burnt to a crisp while fighting Blaze."), - ["mobs_mc:slime"] = N("@1 was slain by Slime."), - ["mobs_mc:witch"] = N("@1 was slain by Witch using magic."), - ["mobs_mc:magma_cube_tiny"] = N("@1 was slain by Magma Cube."), - ["mobs_mc:magma_cube_small"] = N("@1 was slain by Magma Cube."), - ["mobs_mc:magma_cube_big"] = N("@1 was slain by Magma Cube."), - ["mobs_mc:wolf"] = N("@1 was slain by Wolf."), - ["mobs_mc:cat"] = N("@1 was slain by Cat."), - ["mobs_mc:ocelot"] = N("@1 was slain by Ocelot."), - ["mobs_mc:enderdragon"] = N("@1 was slain by Enderdragon."), - ["mobs_mc:wither"] = N("@1 was slain by Wither."), - ["mobs_mc:enderman"] = N("@1 was slain by Enderman."), - ["mobs_mc:endermite"] = N("@1 was slain by Endermite."), - ["mobs_mc:ghast"] = N("@1 was fireballed by a Ghast."), - ["mobs_mc:guardian_elder"] = N("@1 was slain by Elder Guardian."), - ["mobs_mc:guardian"] = N("@1 was slain by Guardian."), - ["mobs_mc:iron_golem"] = N("@1 was slain by Iron Golem."), - ["mobs_mc:polar_bear"] = N("@1 was slain by Polar Bear."), - ["mobs_mc:killer_bunny"] = N("@1 was slain by Killer Bunny."), - ["mobs_mc:shulker"] = N("@1 was slain by Shulker."), - ["mobs_mc:silverfish"] = N("@1 was slain by Silverfish."), - ["mobs_mc:skeleton"] = N("@1 was shot by Skeleton."), - ["mobs_mc:stray"] = N("@1 was shot by Stray."), - ["mobs_mc:slime_tiny"] = N("@1 was slain by Slime."), - ["mobs_mc:slime_small"] = N("@1 was slain by Slime."), - ["mobs_mc:slime_big"] = N("@1 was slain by Slime."), - ["mobs_mc:spider"] = N("@1 was slain by Spider."), - ["mobs_mc:cave_spider"] = N("@1 was slain by Cave Spider."), - ["mobs_mc:vex"] = N("@1 was slain by Vex."), - ["mobs_mc:evoker"] = N("@1 was slain by Evoker."), - ["mobs_mc:illusioner"] = N("@1 was slain by Illusioner."), - ["mobs_mc:vindicator"] = N("@1 was slain by Vindicator."), - ["mobs_mc:villager_zombie"] = N("@1 was slain by Zombie Villager."), - ["mobs_mc:husk"] = N("@1 was slain by Husk."), - ["mobs_mc:baby_husk"] = N("@1 was slain by Baby Husk."), - ["mobs_mc:pigman"] = N("@1 was slain by Zombie Pigman."), - ["mobs_mc:baby_pigman"] = N("@1 was slain by Baby Zombie Pigman."), -} -]]-- local function get_item_killer_message(obj, messages, reason) if messages.item then @@ -217,8 +175,10 @@ local function get_killer_message(obj, messages, reason) return reason.source and (get_item_killer_message(obj, messages, reason) or get_plain_killer_message(obj, messages, reason)) end -local function get_escaped_message(obj, messages, reason) - return nil -- ToDo +local function get_assist_message(obj, messages, reason) + if messages.assist and mcl_death_messages.assist[obj] then + return messages._translator(messages.assist, mcl_util.get_object_name(obj), mcl_death_messages.assist[obj].name) + end end local function get_plain_message(obj, messages, reason) @@ -253,7 +213,7 @@ mcl_damage.register_on_death(function(obj, reason) local message = get_killer_message(obj, messages, reason) or - get_escaped_message(obj, messages, reason) or + get_assist_message(obj, messages, reason) or get_plain_message(obj, messages, reason) or get_fallback_message(obj, messages, reason) @@ -264,3 +224,24 @@ mcl_damage.register_on_death(function(obj, reason) end end end) + +mcl_damage.register_on_damage(function(obj, damage, reason) + if obj:get_hp() - damage > 0 then + if reason.source then + mcl_death_messages.assist[obj] = {name = mcl_util.get_object_name(reason.source), timeout = 5} + else + mcl_death_messages.assist[obj] = nil + end + end +end) + +minetest.register_globalstep(function(dtime) + local new_assist = {} + + for obj, tbl in pairs(mcl_death_messages.assist) do + tbl.timeout = tbl.timeout - dtime + if (obj:is_player() or obj:get_luaentity()) and tbl.timeout > 0 then + new_assist[obj] = tbl + end + end +end) From fede04eaa6ac596e9f1dc3e3af4b1dc968816e79 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 20:20:26 +0200 Subject: [PATCH 42/43] Make armor listring work --- mods/ITEMS/mcl_armor/player.lua | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/mods/ITEMS/mcl_armor/player.lua b/mods/ITEMS/mcl_armor/player.lua index e5471e7e1..9dba0773c 100644 --- a/mods/ITEMS/mcl_armor/player.lua +++ b/mods/ITEMS/mcl_armor/player.lua @@ -84,13 +84,15 @@ local function limit_put(player, inventory, index, stack, count) return 0 end - if mcl_armor.elements[element].index ~= index then + local element_index = mcl_armor.elements[element].index + + if index ~= 1 and index ~= element_index then return 0 end - local old_stack = inventory:get_stack("armor", index) + local old_stack = inventory:get_stack("armor", element_index) - if old_stack:is_empty() or old_stack:get_name() ~= stack:get_name() and count <= 1 then + if old_stack:is_empty() or index ~= 1 and old_stack:get_name() ~= stack:get_name() and count <= 1 then return count else return 0 @@ -125,17 +127,27 @@ minetest.register_allow_player_inventory_action(function(player, action, invento end end) +local function on_put(player, inventory, index, stack) + if index == 1 then + mcl_armor.equip(stack, player) + inventory:set_stack("armor", 1, nil) + else + mcl_armor.on_equip(stack, player) + end +end + minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) if is_armor_action(inventory_info) then if action == "put" then - mcl_armor.on_equip(inventory_info.stack, player) + on_put(player, inventory, inventory_info.index, inventory_info.stack) elseif action == "take" then mcl_armor.on_unequip(inventory_info.stack, player) else + local stack = inventory:get_stack(inventory_info.to_list, inventory_info.to_index) if inventory_info.to_list == "armor" then - mcl_armor.on_equip(inventory:get_stack(inventory_info.to_list, inventory_info.to_index), player) + on_put(player, inventory, inventory_info.to_index, stack) elseif inventory_info.from_list == "armor" then - mcl_armor.on_unequip(inventory:get_stack(inventory_info.to_list, inventory_info.to_index), player) + mcl_armor.on_unequip(stack, player) end end end From edc89898bbab670784b9be8ba1243a1a24baeb9d Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 20:51:13 +0200 Subject: [PATCH 43/43] Integrate fire resistance --- mods/CORE/mcl_damage/init.lua | 54 +++++++++++++++------------- mods/ENTITIES/mcl_burning/api.lua | 18 ++-------- mods/ITEMS/mcl_potions/functions.lua | 33 +++-------------- 3 files changed, 37 insertions(+), 68 deletions(-) diff --git a/mods/CORE/mcl_damage/init.lua b/mods/CORE/mcl_damage/init.lua index 6b343c4c2..983b82b49 100644 --- a/mods/CORE/mcl_damage/init.lua +++ b/mods/CORE/mcl_damage/init.lua @@ -5,7 +5,7 @@ mcl_damage = { types = { in_fire = {is_fire = true}, lightning_bolt = {is_lightning = true}, - on_fire = {is_fire = true}, + on_fire = {is_fire = true, bypasses_armor = true}, lava = {is_fire = true}, hot_floor = {is_fire = true}, in_wall = {bypasses_armor = true}, @@ -93,37 +93,43 @@ function mcl_damage.finish_reason(mcl_reason) end function mcl_damage.from_mt(mt_reason) + if mt_reason._mcl_chached_reason then + return mt_reason._mcl_chached_reason + end + + local mcl_reason + if mt_reason._mcl_reason then - return mt_reason._mcl_reason - end + mcl_reason = mt_reason._mcl_reason + else + mcl_reason = {type = "generic"} - local mcl_reason = {type = "generic"} - - if mt_reason._mcl_type then - mcl_reason.type = mt_reason._mcl_type - elseif mt_reason.type == "fall" then - mcl_reason.type = "fall" - elseif mt_reason.type == "drown" then - mcl_reason.type = "drown" - elseif mt_reason.type == "punch" then - mcl_damage.from_punch(mcl_reason, mt_reason.object) - elseif mt_reason.type == "node_damage" and mt_reason.node then - if minetest.get_item_group(mt_reason.node, "fire") > 0 then - mcl_reason.type = "in_fire" + if mt_reason._mcl_type then + mcl_reason.type = mt_reason._mcl_type + elseif mt_reason.type == "fall" then + mcl_reason.type = "fall" + elseif mt_reason.type == "drown" then + mcl_reason.type = "drown" + elseif mt_reason.type == "punch" then + mcl_damage.from_punch(mcl_reason, mt_reason.object) + elseif mt_reason.type == "node_damage" and mt_reason.node then + if minetest.get_item_group(mt_reason.node, "fire") > 0 then + mcl_reason.type = "in_fire" + end + if minetest.get_item_group(mt_reason.node, "lava") > 0 then + mcl_reason.type = "lava" + end end - if minetest.get_item_group(mt_reason.node, "lava") > 0 then - mcl_reason.type = "lava" - end - end - for key, value in pairs(mt_reason) do - if key:find("_mcl_") == 1 then - mcl_reason[key:sub(6, #key)] = value + for key, value in pairs(mt_reason) do + if key:find("_mcl_") == 1 then + mcl_reason[key:sub(6, #key)] = value + end end end mcl_damage.finish_reason(mcl_reason) - mt_reason._mcl_reason = mcl_reason + mt_reason._mcl_cached_reason = mcl_reason return mcl_reason end diff --git a/mods/ENTITIES/mcl_burning/api.lua b/mods/ENTITIES/mcl_burning/api.lua index 0d299cc69..78814a2c7 100644 --- a/mods/ENTITIES/mcl_burning/api.lua +++ b/mods/ENTITIES/mcl_burning/api.lua @@ -137,22 +137,10 @@ function mcl_burning.tick(obj, dtime, storage) if storage.fire_damage_timer >= 1 then storage.fire_damage_timer = 0 - local hp = mcl_util.get_hp(obj) + local luaentity = obj:get_luaentity() - if hp > 0 then - local do_damage = true - - if obj:is_player() then - if mcl_potions.player_has_effect(obj, "fire_proof") then - do_damage = false - end - elseif obj:get_luaentity().fire_damage_resistant then - do_damage = false - end - - if do_damage then - mcl_util.deal_damage(obj, 1, {reason = "on_fire"}) - end + if not luaentity or not luaentity.fire_damage_resistant then + mcl_util.deal_damage(obj, 1, {type = "on_fire"}) end end end diff --git a/mods/ITEMS/mcl_potions/functions.lua b/mods/ITEMS/mcl_potions/functions.lua index 9f0c88782..9a1e38d99 100644 --- a/mods/ITEMS/mcl_potions/functions.lua +++ b/mods/ITEMS/mcl_potions/functions.lua @@ -344,37 +344,12 @@ minetest.register_globalstep(function(dtime) end) - -local is_fire_node = { ["mcl_core:lava_flowing"]=true, - ["mcl_core:lava_source"]=true, - ["mcl_fire:eternal_fire"]=true, - ["mcl_fire:fire"]=true, - ["mcl_nether:magma"]=true, - ["mcl_nether:nether_lava_source"]=true, - ["mcl_nether:nether_lava_flowing"]=true, - ["mcl_nether:nether_lava_source"]=true -} - -- Prevent damage to player with Fire Resistance enabled -minetest.register_on_player_hpchange(function(player, hp_change, reason) - - if EF.fire_proof[player] and hp_change < 0 then - -- This is a bit forced, but it assumes damage is taken by fire and avoids it - -- also assumes any change in hp happens between calls to this function - -- it's worth noting that you don't take damage from players in this case... - local player_info = mcl_playerinfo[player:get_player_name()] - - if is_fire_node[player_info.node_head] or is_fire_node[player_info.node_feet] or is_fire_node[player_info.node_stand] then - return 0 - else - return hp_change - end - - else - return hp_change +mcl_damage.register_modifier(function(obj, damage, reason) + if EF.fire_proof[obj] and not reason.flags.bypasses_magic and reason.flags.is_fire then + return 0 end - -end, true) +end, -50)