-function tnt(pos,range)
- local pos = vector.floor(vector.add(pos,0.5))
- local min = vector.add(pos,range)
- local max = vector.subtract(pos,range)
- local vm = minetest.get_voxel_manip()
- local emin, emax = vm:read_from_map(min,max)
- local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
- local data = vm:get_data()
-
- local air = minetest.get_content_id("air")
- local content_id = minetest.get_name_from_content_id
-
- local insert = table.insert
-
- vm:get_light_data()
+local in_node
+local in_water
+local min
+local max
+local vm
+local emin
+local emax
+local area
+local data
+local air = minetest.get_content_id("air")
+local content_id = minetest.get_name_from_content_id
+local distance
+local item
+local ppos
+local obj
+local do_it
+local in_node
+local clear
+local power
+local dir
+local force
+local hp
+local explosion_force
+local explosion_depletion
+local range_calc
+local boom_time = minetest.get_us_time()/1000000
+local digging_nodes = {
+ ["utility:chest_open"] = true,
+ ["utility:chest"] = true,
+ ["utility:furnace_active"] = true,
+ ["utility:furnace"] = true,
+}
+function tnt(pos,range,explosion_type)
+ in_node = minetest.get_node(pos).name
+ in_water = ( in_node == "main:water" or minetest.get_node(pos).name == "main:waterflow")
+ min = vector.add(pos,range)
+ max = vector.subtract(pos,range)
+ vm = minetest.get_voxel_manip(min,max)
+ emin, emax = vm:read_from_map(min,max)
+ area = VoxelArea:new{MinEdge=emin, MaxEdge=emax}
+ data = vm:get_data()
+
+ if in_water == false then
+ vm:get_light_data()
+ range_calc = range/100
+ explosion_depletion = range/2
+ --raycast explosion
+ for x=-range, range do
+ for y=-range, range do
+ for z=-range, range do
+ distance = vector.distance(pos2, vector.new(x,y,z))
+ if distance <= range and distance >= range-1 then
+ ray = minetest.raycast(pos, vector.new(pos.x+x,pos.y+y,pos.z+z), false, false)
+ explosion_force = range
+ for pointed_thing in ray do
+ explosion_force = explosion_force - math.random()
+ if pointed_thing and explosion_force >= explosion_depletion then
+ n_pos = area:index(pointed_thing.under.x,pointed_thing.under.y,pointed_thing.under.z)
+
+ if n_pos and data[n_pos] then
+ node2 = content_id(data[n_pos])
+
+ if node2 == "nether:obsidian" or node2 == "nether:bedrock" then
+ break
+ elseif digging_nodes[node2] then
+ minetest.dig_node({x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z})
+ data[n_pos] = air
+ elseif node2 == "tnt:tnt" then
+ data[n_pos] = air
+ minetest.add_entity({x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z}, "tnt:tnt",minetest.serialize({do_ignition_particles=true,timer = math.random()}))
+ elseif not string.match(node2, "mob_spawners:") then
+ data[n_pos] = air
+
+ minetest.after(0, function(pointed_thing)
+ minetest.check_for_falling({x=pointed_thing.under.x,y=pointed_thing.under.y+1,z=pointed_thing.under.z})
+ end,pointed_thing)
+ if range_calc < 1 and math.random() > 0.9 + range_calc then
+ item = minetest.get_node_drops(node2, "main:diamondpick")[1]
+ ppos = {x=pointed_thing.under.x,y=pointed_thing.under.y,z=pointed_thing.under.z}
+ obj = minetest.add_item(ppos, item)
+ if obj then
+ power = (range - vector.distance(pos,ppos))*2
+ dir = vector.subtract(ppos,pos)
+ force = vector.multiply(dir,power)
+ obj:set_velocity(force)
+ end
+ end
+ end
+ end
+ else
+ break
+ end
+ end
+ end
+ end
+ end
+ end
+ vm:set_data(data)
+ vm:update_liquids()
+ vm:write_to_map()
+ end
+ if minetest.get_us_time()/1000000 - boom_time >= 0.1 then
+ boom_time = minetest.get_us_time()/1000000
+ minetest.sound_play("tnt_explode", {pos = pos, gain = 1.0, max_hear_distance = 64}) --hear twice as far away
+ end