New damage system (WIP)

This commit is contained in:
Elias Fleckenstein 2021-03-18 15:05:08 +01:00
parent 422076f761
commit 8f735cc644
5 changed files with 43 additions and 33 deletions

View file

@ -1,10 +1,16 @@
MCLDamageSource = class() MCLDamageSource = class()
function MCLDamageSource:constructor(tbl) function MCLDamageSource:constructor(tbl)
for k, v in pairs(tbl or {}) do if tbl then
for k, v in pairs(tbl) do
self[k] = v self[k] = v
end end
end end
end
function MCLDamageSource:from_mt(reason)
end
MCLDamageSource:__getter("direct_object", function(self) MCLDamageSource:__getter("direct_object", function(self)
local obj = self.raw_source_object local obj = self.raw_source_object

View file

@ -8,15 +8,15 @@ end
function MCLObject:on_punch(hitter, time_from_last_punch, tool_capabilities, dir, damage) function MCLObject:on_punch(hitter, time_from_last_punch, tool_capabilities, dir, damage)
local source = MCLDamageSource({is_punch = true, raw_source_object = hitter}) local source = MCLDamageSource({is_punch = true, raw_source_object = hitter})
damage = self:damage_modifier(damage, source) or damage local knockback = {
hitter = hitter,
self.damage_info = { time_from_last_punch = time_from_last_punch,
damage = damage, tool_capabilities = tool_capabilities,
source = source, dir = dir,
knockback = self:get_knockback(source, time_from_last_punch, tool_capabilities, dir, nil, damage),
} }
return damage self:damage(damage, source, knockback)
return true
end end
-- use this function to deal regular damage to an object (do NOT use :punch() unless toolcaps need to be handled) -- use this function to deal regular damage to an object (do NOT use :punch() unless toolcaps need to be handled)
@ -24,11 +24,22 @@ function MCLObject:damage(damage, source, knockback)
damage = self:damage_modifier(damage, source) or damage damage = self:damage_modifier(damage, source) or damage
self:set_hp(self:get_hp() - damage) self:set_hp(self:get_hp() - damage)
self.damage_info = { if type(knockback) == "table" then
knockback = self:calculate_knockback(
knockback.hitter,
knockback.time_from_last_punch,
knockback.tool_capabilities,
knockback.dir or vector.direction(knockback.hitter:get_pos(), self.object:get_pos(),
knockback.distance or vector.distance(knockback.hitter:get_pos(), self.object:get_pos(),
damage,
source)
end
table.insert(self.damage_info, {
damage = damage, damage = damage,
source = source, source = source,
knockback = knockback, knockback = knockback,
} })
return damage return damage
end end
@ -75,22 +86,12 @@ end
function MCLObject:on_damage(damage, source, knockback) function MCLObject:on_damage(damage, source, knockback)
end end
function MCLObject:get_knockback(source, time_from_last_punch, tool_capabilities, dir, distance, damage)
local direct_object = source:direct_object()
return self:calculate_knockback(
self.object,
direct_object,
time_from_last_punch or 1.0,
tool_capabilities or {fleshy = damage},
dir or vector.direction(direct_object:get_pos(), self.object:get_pos()),
distance or vector.distance(direct_object:get_pos(), self.object:get_pos()),
damage = damage,
)
end
MCLObject.calculate_knockback = minetest.calculate_knockback MCLObject.calculate_knockback = minetest.calculate_knockback
function minetest.calculate_knockback()
return 0
end
function MCLObject:on_step() function MCLObject:on_step()
local damage_info = self.damage_info local damage_info = self.damage_info
if damage_info then if damage_info then

View file

@ -70,6 +70,7 @@ function mcl_object_mgr.register_entity(name, initial_properties, base_class)
add_entity_wrapper(def, "on_deactivate") add_entity_wrapper(def, "on_deactivate")
add_entity_wrapper(def, "on_step") add_entity_wrapper(def, "on_step")
add_entity_wrapper(def, "on_punch")
add_entity_wrapper(def, "on_death") add_entity_wrapper(def, "on_death")
add_entity_wrapper(def, "on_rightclick") add_entity_wrapper(def, "on_rightclick")
add_entity_wrapper(def, "on_attach_child") add_entity_wrapper(def, "on_attach_child")
@ -109,4 +110,12 @@ add_player_wrapper("on_rightclick")
add_player_wrapper("on_death", "register_on_dieplayer") add_player_wrapper("on_death", "register_on_dieplayer")
add_player_wrapper("on_respawn") add_player_wrapper("on_respawn")
minetest.register_on_player_hpchange(function(player, hp_change, reason)) minetest.register_on_player_hpchange(function(player, hp_change, reason)
if not reason.auto then
local mclplayer = mcl_object_mgr.get(player)
local source = MCLDamageSource():from_mt(reason)
mclplayer:damage(hp_change, source)
return true
end
end, true)

View file

@ -14,12 +14,6 @@ MCLPlayer:__override_pipe("death_drop", function(self, inventory, listname, inde
end end
end) end)
function MCLPlayer:get_knockback(source, ...)
if not source.is_punch then
return MCLObject.get_knockback(self, source, ...)
end
end
function MCLPlayer:on_damage(damage, source, knockback) function MCLPlayer:on_damage(damage, source, knockback)
MCLObject.on_damage(self, damage, source, knockback) MCLObject.on_damage(self, damage, source, knockback)
end end

View file

@ -87,7 +87,7 @@ function MCLObject:damage_modifier(damage, source)
if thorns_damage > 0 and source_object ~= self then if thorns_damage > 0 and source_object ~= self then
local thorns_damage_source = MCLDamageSource({direct_object = self, source_object = source_object, is_thorns = true}) local thorns_damage_source = MCLDamageSource({direct_object = self, source_object = source_object, is_thorns = true})
local thorns_knockback = source_object:get_knockback(thorns_damage_source, nil, nil, nil, nil, thorns_damage) local thorns_knockback = {hitter = self}
source_object:damage(thorns_damage, thorns_damage_source, thorns_knockback) source_object:damage(thorns_damage, thorns_damage_source, thorns_knockback)