TNT: Allow mods to override entity physics.

Introduces an `on_blast(luaobj, damage)` callback that mods can attach
to an entity def. The function will get called with the damage that
TNT would make.

The function should return three values:

  bool do_damage, bool do_knockback, table drops

do_damage allows the mod to tell the TNT code to perform damage on
the entity for the mod. The mod code should not do anything with
the entity HP. The entity should not be immortal. If false, then
the entity will not be damaged by the TNT mod.

do_knockback allows the mod to tell the TNT mod to perform an
entity knockback effect. If false, no knockback effect is applied
to the entity.

the drops table is a list of items to drop. It may be nil. E.g. {
"wool:red" }.

I've documented both on_blast() API methods in game_api.txt. It is
a better place than lua_api.txt.
This commit is contained in:
Auke Kok 2016-04-27 20:15:52 -07:00 committed by paramat
parent b56c7c0703
commit 43cf4a4984

@ -138,7 +138,7 @@ local function calc_velocity(pos1, pos2, old_vel, power)
return vel return vel
end end
local function entity_physics(pos, radius) local function entity_physics(pos, radius, drops)
local objs = minetest.get_objects_inside_radius(pos, radius) local objs = minetest.get_objects_inside_radius(pos, radius)
for _, obj in pairs(objs) do for _, obj in pairs(objs) do
local obj_pos = obj:getpos() local obj_pos = obj:getpos()
@ -157,14 +157,31 @@ local function entity_physics(pos, radius)
obj:set_hp(obj:get_hp() - damage) obj:set_hp(obj:get_hp() - damage)
else else
local obj_vel = obj:getvelocity() local do_damage = true
obj:setvelocity(calc_velocity(pos, obj_pos, local do_knockback = true
obj_vel, radius * 10)) local entity_drops = {}
if not obj:get_armor_groups().immortal then local luaobj = obj:get_luaentity()
obj:punch(obj, 1.0, { local objdef = minetest.registered_entities[luaobj.name]
full_punch_interval = 1.0,
damage_groups = {fleshy = damage}, if objdef and objdef.on_blast then
}, nil) do_damage, do_knockback, entity_drops = objdef.on_blast(luaobj, damage)
end
if do_knockback then
local obj_vel = obj:getvelocity()
obj:setvelocity(calc_velocity(pos, obj_pos,
obj_vel, radius * 10))
end
if do_damage then
if not obj:get_armor_groups().immortal then
obj:punch(obj, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = damage},
}, nil)
end
end
for _, item in ipairs(entity_drops) do
add_drop(drops, item)
end end
end end
end end
@ -303,7 +320,9 @@ function tnt.boom(pos, def)
minetest.set_node(pos, {name = "tnt:boom"}) minetest.set_node(pos, {name = "tnt:boom"})
local drops = tnt_explode(pos, def.radius, def.ignore_protection, local drops = tnt_explode(pos, def.radius, def.ignore_protection,
def.ignore_on_blast) def.ignore_on_blast)
entity_physics(pos, def.damage_radius) -- append entity drops
entity_physics(pos, def.damage_radius, drops)
if not def.disable_drops then if not def.disable_drops then
eject_drops(drops, pos, def.radius) eject_drops(drops, pos, def.radius)
end end