From 6aecae6eea436849b9a80dbfa99bb0aa42c31d84 Mon Sep 17 00:00:00 2001 From: Elias Fleckenstein Date: Sun, 25 Apr 2021 13:50:07 +0200 Subject: [PATCH] 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 bc5280841c..24c5fb42cb 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 741dc604e7..a2a1ea816c 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)