diff --git a/game_api.txt b/game_api.txt index 02ee58e0..8e621c87 100644 --- a/game_api.txt +++ b/game_api.txt @@ -258,6 +258,28 @@ parameter, and drops is not reinitialized so you can call it several times in a row to add more inventory items to it. +`on_blast` callbacks: + +Both nodedefs and entitydefs can provide an `on_blast()` callback + +`nodedef.on_blast(pos, intensity)` +^ Allow drop and node removal overriding +* `pos` - node position +* `intensity` - TNT explosion measure. larger or equal to 1.0 +^ Should return a list of drops (e.g. {"default:stone"}) +^ Should perform node removal itself. If callback exists in the nodedef +^ then the TNT code will not destroy this node. + +`entitydef.on_blast(luaobj, damage)` +^ Allow TNT effects on entities to be overridden +* `luaobj` - LuaEntityRef of the entity +* `damage` - suggested HP damage value +^ Should return a list of (bool do_damage, bool do_knockback, table drops) +* `do_damage` - if true then TNT mod wil damage the entity +* `do_knockback` - if true then TNT mod will knock the entity away +* `drops` - a list of drops, e.g. {"wool:red"} + + Screwdriver API --------------- diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index d61cbf13..d3efd7b8 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -138,7 +138,7 @@ local function calc_velocity(pos1, pos2, old_vel, power) return vel end -local function entity_physics(pos, radius) +local function entity_physics(pos, radius, drops) local objs = minetest.get_objects_inside_radius(pos, radius) for _, obj in pairs(objs) do local obj_pos = obj:getpos() @@ -157,14 +157,31 @@ local function entity_physics(pos, radius) obj:set_hp(obj:get_hp() - damage) else - local obj_vel = obj:getvelocity() - obj:setvelocity(calc_velocity(pos, obj_pos, - obj_vel, radius * 10)) - if not obj:get_armor_groups().immortal then - obj:punch(obj, 1.0, { - full_punch_interval = 1.0, - damage_groups = {fleshy = damage}, - }, nil) + local do_damage = true + local do_knockback = true + local entity_drops = {} + local luaobj = obj:get_luaentity() + local objdef = minetest.registered_entities[luaobj.name] + + if objdef and objdef.on_blast then + 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 @@ -303,7 +320,9 @@ function tnt.boom(pos, def) minetest.set_node(pos, {name = "tnt:boom"}) local drops = tnt_explode(pos, def.radius, def.ignore_protection, 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 eject_drops(drops, pos, def.radius) end