diff --git a/game_api.txt b/game_api.txt
index 02ee58e0876bde5029e0c58dbe89ef5fa572186e..8e621c877de334897f1df7861bdec69dd18e97f6 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 d61cbf13df4c5ace8d4b0d7f953635a80218ea56..d3efd7b8c9140bd34a2ca99d90ba6297595d3366 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