From 6fdfd2554c23535530a5750d3b362e6399b00b55 Mon Sep 17 00:00:00 2001 From: tenplus1 Date: Wed, 5 Oct 2016 16:15:49 +0100 Subject: [PATCH] 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. --- .luacheckrc | 2 +- game_api.txt | 4 ++-- mods/tnt/init.lua | 29 ++++++++++++++++------------- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/.luacheckrc b/.luacheckrc index f087d303..3a4faccb 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -5,7 +5,7 @@ read_globals = { "DIR_DELIM", "minetest", "core", "dump", - "vector", "nodeupdate", + "vector", "nodeupdate", "nodeupdate_single", "VoxelManip", "VoxelArea", "PseudoRandom", "ItemStack", } diff --git a/game_api.txt b/game_api.txt index 9e8d4963..a148136d 100644 --- a/game_api.txt +++ b/game_api.txt @@ -290,9 +290,9 @@ TNT API * `position` The center of explosion. * `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 diff --git a/mods/tnt/init.lua b/mods/tnt/init.lua index 1e6e29d5..1138e1c2 100644 --- a/mods/tnt/init.lua +++ b/mods/tnt/init.lua @@ -99,7 +99,7 @@ local function destroy(drops, npos, cid, c_air, c_fire, on_blast_queue, ignore_p return c_fire else 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) end return c_air @@ -181,7 +181,7 @@ local function entity_physics(pos, radius, drops) }, nil) end end - for _, item in ipairs(entity_drops) do + for _, item in pairs(entity_drops) do add_drop(drops, item) end end @@ -248,8 +248,8 @@ local function add_effects(pos, radius, drops) }) end -function tnt.burn(pos) - local name = minetest.get_node(pos).name +function tnt.burn(pos, nodename) + local name = nodename or minetest.get_node(pos).name local group = minetest.get_item_group(name, "tnt") if group > 0 then 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() -- 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 x = -radius * 1.5, radius * 1.5 do - for y = -radius * 1.5, radius * 1.5 do - local s = vector.add(pos, {x = x, y = y, z = z}) - local r = vector.distance(pos, s) + local rad = {x = x, y = y, z = z} + local s = vector.add(pos, rad) + local r = vector.length(rad) if r / radius < 1.4 then - nodeupdate(s) + nodeupdate_single(s) 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 intensity = (radius * radius) / (dist * dist) local node_drops = queued_data.on_blast(queued_data.pos, intensity) if node_drops then - for _, item in ipairs(node_drops) do + for _, item in pairs(node_drops) do add_drop(drops, item) end end @@ -408,11 +409,11 @@ minetest.register_node("tnt:gunpowder", { on_punch = function(pos, node, puncher) if puncher:get_wielded_item():get_name() == "default:torch" then - tnt.burn(pos) + tnt.burn(pos, node.name) end end, on_blast = function(pos, intensity) - tnt.burn(pos) + tnt.burn(pos, "tnt:gunpowder") end, }) @@ -511,7 +512,9 @@ if enable_tnt then neighbors = {"fire:basic_flame", "default:lava_source", "default:lava_flowing"}, interval = 4, chance = 1, - action = tnt.burn, + action = function(pos, node) + tnt.burn(pos, node.name) + end, }) end