Tnt: Various optimisations

Pass nodename to tnt.burn function where possible to reduce
use of 'get_node'.
Change 'ipairs' to 'pairs'.
Use 'nodeupdate_single(pos)' instead of 'nodeupdate(pos)' to
avoid every node triggering recursion, the loop itself takes
the place of recursion and works upwards through horizontal
planes as required.
This commit is contained in:
tenplus1 2016-10-05 16:15:49 +01:00 committed by paramat
parent 53179b8d10
commit 6fdfd2554c
3 changed files with 19 additions and 16 deletions

View File

@ -5,7 +5,7 @@ read_globals = {
"DIR_DELIM", "DIR_DELIM",
"minetest", "core", "minetest", "core",
"dump", "dump",
"vector", "nodeupdate", "vector", "nodeupdate", "nodeupdate_single",
"VoxelManip", "VoxelArea", "VoxelManip", "VoxelArea",
"PseudoRandom", "ItemStack", "PseudoRandom", "ItemStack",
} }

View File

@ -290,9 +290,9 @@ TNT API
* `position` The center of explosion. * `position` The center of explosion.
* `definition` The TNT definion as passed to `tnt.register` * `definition` The TNT definion as passed to `tnt.register`
`tnt.burn(position)` `tnt.burn(position, [nodename])`
^ Ignite TNT at position ^ Ignite TNT at position, nodename isn't required unless already known.
To make dropping items from node inventories easier, you can use the To make dropping items from node inventories easier, you can use the

View File

@ -99,7 +99,7 @@ local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_p
return c_fire return c_fire
else else
local node_drops = minetest.get_node_drops(def.name, "") local node_drops = minetest.get_node_drops(def.name, "")
for _, item in ipairs(node_drops) do for _, item in pairs(node_drops) do
add_drop(drops, item) add_drop(drops, item)
end end
return c_air return c_air
@ -181,7 +181,7 @@ local function entity_physics(pos, radius, drops)
}, nil) }, nil)
end end
end end
for _, item in ipairs(entity_drops) do for _, item in pairs(entity_drops) do
add_drop(drops, item) add_drop(drops, item)
end end
end end
@ -248,8 +248,8 @@ local function add_effects(pos, radius, drops)
}) })
end end
function tnt.burn(pos) function tnt.burn(pos, nodename)
local name = minetest.get_node(pos).name local name = nodename or minetest.get_node(pos).name
local group = minetest.get_item_group(name, "tnt") local group = minetest.get_item_group(name, "tnt")
if group > 0 then if group > 0 then
minetest.sound_play("tnt_ignite", {pos = pos}) minetest.sound_play("tnt_ignite", {pos = pos})
@ -333,24 +333,25 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast)
vm:update_liquids() vm:update_liquids()
-- call nodeupdate for everything within 1.5x blast radius -- call nodeupdate for everything within 1.5x blast radius
for y = -radius * 1.5, radius * 1.5 do
for z = -radius * 1.5, radius * 1.5 do for z = -radius * 1.5, radius * 1.5 do
for x = -radius * 1.5, radius * 1.5 do for x = -radius * 1.5, radius * 1.5 do
for y = -radius * 1.5, radius * 1.5 do local rad = {x = x, y = y, z = z}
local s = vector.add(pos, {x = x, y = y, z = z}) local s = vector.add(pos, rad)
local r = vector.distance(pos, s) local r = vector.length(rad)
if r / radius < 1.4 then if r / radius < 1.4 then
nodeupdate(s) nodeupdate_single(s)
end end
end end
end end
end end
for _, queued_data in ipairs(on_blast_queue) do for _, queued_data in pairs(on_blast_queue) do
local dist = math.max(1, vector.distance(queued_data.pos, pos)) local dist = math.max(1, vector.distance(queued_data.pos, pos))
local intensity = (radius * radius) / (dist * dist) local intensity = (radius * radius) / (dist * dist)
local node_drops = queued_data.on_blast(queued_data.pos, intensity) local node_drops = queued_data.on_blast(queued_data.pos, intensity)
if node_drops then if node_drops then
for _, item in ipairs(node_drops) do for _, item in pairs(node_drops) do
add_drop(drops, item) add_drop(drops, item)
end end
end end
@ -408,11 +409,11 @@ minetest.register_node("tnt:gunpowder", {
on_punch = function(pos, node, puncher) on_punch = function(pos, node, puncher)
if puncher:get_wielded_item():get_name() == "default:torch" then if puncher:get_wielded_item():get_name() == "default:torch" then
tnt.burn(pos) tnt.burn(pos, node.name)
end end
end, end,
on_blast = function(pos, intensity) on_blast = function(pos, intensity)
tnt.burn(pos) tnt.burn(pos, "tnt:gunpowder")
end, end,
}) })
@ -511,7 +512,9 @@ if enable_tnt then
neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"},
interval = 4, interval = 4,
chance = 1, chance = 1,
action = tnt.burn, action = function(pos, node)
tnt.burn(pos, node.name)
end,
}) })
end end