Skip to content

Commit

Permalink
TNT: Allow mods to override entity physics.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sofar authored and paramat committed Apr 30, 2016
1 parent f14b411 commit 098ea0d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 10 deletions.
22 changes: 22 additions & 0 deletions game_api.txt
Expand Up @@ -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
---------------

Expand Down
39 changes: 29 additions & 10 deletions mods/tnt/init.lua
Expand Up @@ -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()
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 098ea0d

Please sign in to comment.