2017-01-16 13:59:16 +00:00
local function spawn_tnt ( pos , entname )
2017-02-27 22:45:26 +00:00
minetest.sound_play ( " tnt_ignite " , { pos = pos , gain = 1.0 , max_hear_distance = 15 , } )
local tnt = minetest.add_entity ( pos , entname )
tnt : set_armor_groups ( { immortal = 1 } )
2017-03-04 22:25:02 +00:00
return tnt
2015-06-29 17:55:56 +00:00
end
2017-01-16 13:59:16 +00:00
local function activate_if_tnt ( nname , np , tnt_np , tntr )
2017-01-26 10:23:09 +00:00
if nname == " mcl_tnt:tnt " then
2015-06-29 17:55:56 +00:00
local e = spawn_tnt ( np , nname )
e : setvelocity ( { x = ( np.x - tnt_np.x ) * 5 + ( tntr / 4 ) , y = ( np.y - tnt_np.y ) * 5 + ( tntr / 3 ) , z = ( np.z - tnt_np.z ) * 5 + ( tntr / 4 ) } )
end
end
2017-01-16 13:59:16 +00:00
local function do_tnt_physics ( tnt_np , tntr )
2017-01-11 17:21:46 +00:00
local objs = minetest.get_objects_inside_radius ( tnt_np , tntr )
2015-06-29 17:55:56 +00:00
for k , obj in pairs ( objs ) do
local oname = obj : get_entity_name ( )
local v = obj : getvelocity ( )
local p = obj : getpos ( )
2017-01-26 10:23:09 +00:00
if oname == " mcl_tnt:tnt " then
2015-06-29 17:55:56 +00:00
obj : setvelocity ( { x = ( p.x - tnt_np.x ) + ( tntr / 2 ) + v.x , y = ( p.y - tnt_np.y ) + tntr + v.y , z = ( p.z - tnt_np.z ) + ( tntr / 2 ) + v.z } )
else
if v ~= nil then
obj : setvelocity ( { x = ( p.x - tnt_np.x ) + ( tntr / 4 ) + v.x , y = ( p.y - tnt_np.y ) + ( tntr / 2 ) + v.y , z = ( p.z - tnt_np.z ) + ( tntr / 4 ) + v.z } )
else
if obj : get_player_name ( ) ~= nil then
obj : set_hp ( obj : get_hp ( ) - 1 )
end
end
end
end
end
2017-01-16 13:59:16 +00:00
tnt = { }
tnt.ignite = function ( pos )
minetest.remove_node ( pos )
2017-01-26 10:23:09 +00:00
spawn_tnt ( pos , " mcl_tnt:tnt " )
2017-01-26 18:14:07 +00:00
core.check_for_falling ( pos )
2017-01-16 13:59:16 +00:00
end
2017-03-11 19:54:27 +00:00
local TNT_RANGE = 3
2017-01-16 13:59:16 +00:00
2017-01-26 10:23:09 +00:00
minetest.register_node ( " mcl_tnt:tnt " , {
2017-01-16 12:00:20 +00:00
tiles = { " default_tnt_top.png " , " default_tnt_bottom.png " ,
2015-06-29 17:55:56 +00:00
" default_tnt_side.png " , " default_tnt_side.png " ,
" default_tnt_side.png " , " default_tnt_side.png " } ,
2017-01-04 21:36:51 +00:00
is_ground_content = false ,
2015-06-29 17:55:56 +00:00
stack_max = 64 ,
description = " TNT " ,
2017-03-11 19:54:27 +00:00
_doc_items_longdesc = string.format ( " An explosive device. When it explodes, it will hurt living beings, destroy blocks around it, throw blocks affected by gravity all over the place and light fires. A single TNT has an explosion radius of %d. With a small chance, blocks may drop as an item (as if being mined) rather than being destroyed. TNT can be ignited by tools, explosions, igniter blocks and redstone signals. " , TNT_RANGE ) ,
_doc_items_usagehelp = " Place the TNT on the ground and ignite it with one of the methods above. Quickly get in safe distance quickly. The TNT will start to be affected by gravity and explodes in 4 seconds. " ,
2017-01-21 13:32:23 +00:00
groups = { dig_immediate = 3 , tnt = 1 , } ,
2015-06-29 17:55:56 +00:00
mesecons = { effector = {
2017-01-16 13:59:16 +00:00
action_on = tnt.ignite
2017-01-04 23:18:59 +00:00
} } ,
2017-05-09 15:49:38 +00:00
_on_ignite = function ( pos , player )
tnt.ignite ( pos )
end ,
2017-02-11 17:46:23 +00:00
sounds = mcl_sounds.node_sound_wood_defaults ( ) ,
2015-06-29 17:55:56 +00:00
} )
local TNT = {
-- Static definition
physical = true , -- Collides with things
--weight = -100,
collisionbox = { - 0.5 , - 0.5 , - 0.5 , 0.5 , 0.5 , 0.5 } ,
visual = " cube " ,
textures = { " default_tnt_top.png " , " default_tnt_bottom.png " ,
" default_tnt_side.png " , " default_tnt_side.png " ,
" default_tnt_side.png " , " default_tnt_side.png " } ,
-- Initial value for our timer
timer = 0 ,
-- Number of punches required to defuse
health = 1 ,
blinktimer = 0 ,
blinkstatus = true , }
function TNT : on_activate ( staticdata )
self.object : setvelocity ( { x = 0 , y = 4 , z = 0 } )
self.object : setacceleration ( { x = 0 , y =- 10 , z = 0 } )
2017-01-26 10:27:20 +00:00
self.object : settexturemod ( " ^mcl_tnt_blink.png " )
2015-06-29 17:55:56 +00:00
end
function TNT : on_step ( dtime )
local pos = self.object : getpos ( )
2017-02-10 15:03:38 +00:00
minetest.add_particle ( {
pos = { x = pos.x , y = pos.y + 0.5 , z = pos.z } ,
velocity = { x = math.random ( - .1 , .1 ) , y = math.random ( 1 , 2 ) , z = math.random ( - .1 , .1 ) } ,
acceleration = { x = 0 , y =- 0.1 , z = 0 } ,
expirationtime = math.random ( .5 , 1 ) ,
size = math.random ( 1 , 2 ) ,
collisiondetection = false ,
texture = " tnt_smoke.png "
} )
2015-06-29 17:55:56 +00:00
self.timer = self.timer + dtime
self.blinktimer = self.blinktimer + dtime
2017-03-11 20:00:49 +00:00
if self.blinktimer > 0.25 then
self.blinktimer = self.blinktimer - 0.25
2015-06-29 17:55:56 +00:00
if self.blinkstatus then
self.object : settexturemod ( " " )
else
2017-01-26 10:23:09 +00:00
self.object : settexturemod ( " ^mcl_tnt_blink.png " )
2015-06-29 17:55:56 +00:00
end
self.blinkstatus = not self.blinkstatus
end
2017-01-04 23:20:21 +00:00
if self.timer > 4 then
2015-06-29 17:55:56 +00:00
local pos = self.object : getpos ( )
pos.x = math.floor ( pos.x + 0.5 )
pos.y = math.floor ( pos.y + 0.5 )
pos.z = math.floor ( pos.z + 0.5 )
do_tnt_physics ( pos , TNT_RANGE )
2017-01-11 17:21:46 +00:00
local meta = minetest.get_meta ( pos )
2015-06-29 17:55:56 +00:00
minetest.sound_play ( " tnt_explode " , { pos = pos , gain = 1.0 , max_hear_distance = 16 , } )
2017-01-31 22:32:56 +00:00
if minetest.get_node ( pos ) . name == " mcl_core:water_source " or minetest.get_node ( pos ) . name == " mcl_core:water_flowing " or minetest.get_node ( pos ) . name == " mcl_core:bedrock " or minetest.get_node ( pos ) . name == " protector:display " or minetest.is_protected ( pos , " tnt " ) then
2015-06-29 17:55:56 +00:00
-- Cancel the Explosion
self.object : remove ( )
return
end
for x =- TNT_RANGE , TNT_RANGE do
for y =- TNT_RANGE , TNT_RANGE do
for z =- TNT_RANGE , TNT_RANGE do
if x * x + y * y + z * z <= TNT_RANGE * TNT_RANGE + TNT_RANGE then
local np = { x = pos.x + x , y = pos.y + y , z = pos.z + z }
2017-01-11 17:21:46 +00:00
local n = minetest.get_node ( np )
2017-01-31 22:32:56 +00:00
if n.name ~= " air " and n.name ~= " mcl_core:obsidian " and n.name ~= " mcl_core:bedrock " and n.name ~= " protector:protect " then
2015-06-29 17:55:56 +00:00
activate_if_tnt ( n.name , np , pos , 3 )
2017-01-11 17:21:46 +00:00
minetest.remove_node ( np )
2017-01-26 18:14:07 +00:00
core.check_for_falling ( np )
2017-01-26 10:23:09 +00:00
if n.name ~= " mcl_tnt:tnt " and math.random ( ) > 0.9 then
2015-06-29 17:55:56 +00:00
local drop = minetest.get_node_drops ( n.name , " " )
for _ , item in ipairs ( drop ) do
if type ( item ) == " string " then
if math.random ( 1 , 100 ) > 40 then
2017-01-11 17:21:46 +00:00
local obj = minetest.add_item ( np , item )
2015-06-29 17:55:56 +00:00
end
end
end
end
end
end
end
end
self.object : remove ( )
end
end
end
2017-01-26 10:23:09 +00:00
minetest.register_entity ( " mcl_tnt:tnt " , TNT )
2015-06-29 17:55:56 +00:00
minetest.register_craft ( {
2017-01-26 10:23:09 +00:00
output = " mcl_tnt:tnt " ,
2015-06-29 17:55:56 +00:00
recipe = {
2017-02-16 20:33:14 +00:00
{ ' mcl_mobitems:gunpowder ' , ' group:sand ' , ' mcl_mobitems:gunpowder ' } ,
{ ' group:sand ' , ' mcl_mobitems:gunpowder ' , ' group:sand ' } ,
{ ' mcl_mobitems:gunpowder ' , ' group:sand ' , ' mcl_mobitems:gunpowder ' }
2015-06-29 17:55:56 +00:00
}
2017-01-04 21:36:51 +00:00
} )
2017-03-21 03:36:18 +00:00
if minetest.get_modpath ( " doc_identifier " ) then
doc.sub . identifier.register_object ( " mcl_tnt:tnt " , " nodes " , " mcl_tnt:tnt " )
end