From d61803b65f22b5cd32f7938c64578b04dd437154 Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Sat, 12 Mar 2016 20:19:37 -0800 Subject: [PATCH] Fire: move fire node removal out of ABM. Because the fire nodes are not removed 100% when there are no more burnable nodes nearby, they can potentially stay around for very, very long times, leading to ABM trains every 5 seconds for no good reason (only 1 in 16 will be removed every interval). A much better method to remove fire nodes is to remove them by timer, and give removal a 100% chance if no flammable nodes are adjacent. This makes fire cleanup a lot faster and more natural, and will reduce the amount of ABM hits making fire overall more responsive. We also remove the 1 in 4 chance and fold the removal of flammable nodes into the ABM chance. There's some low hanging fruit cleanups in here as well. --- mods/fire/init.lua | 56 +++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/mods/fire/init.lua b/mods/fire/init.lua index 457f6b5..832b701 100644 --- a/mods/fire/init.lua +++ b/mods/fire/init.lua @@ -28,14 +28,24 @@ minetest.register_node("fire:basic_flame", { sunlight_propagates = true, damage_per_second = 4, groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1}, + on_timer = function(pos) + local f = minetest.find_node_near(pos, 1, {"group:flammable"}) + if not f then + minetest.remove_node(pos) + return + end + -- restart timer + return true + end, drop = "", on_construct = function(pos) - minetest.after(0, fire.on_flame_add_at, pos) + minetest.get_node_timer(pos):start(math.random(30, 60)) + minetest.after(0, fire.update_sounds_around, pos) end, on_destruct = function(pos) - minetest.after(0, fire.on_flame_remove_at, pos) + minetest.after(0, fire.update_sounds_around, pos) end, on_blast = function() @@ -169,32 +179,6 @@ function fire.update_sounds_around(pos) end --- Update fire sounds on flame node construct or destruct - -function fire.on_flame_add_at(pos) - fire.update_sounds_around(pos) -end - - -function fire.on_flame_remove_at(pos) - fire.update_sounds_around(pos) -end - - --- Return positions for flames around a burning node - -function fire.find_pos_for_flame_around(pos) - return minetest.find_node_near(pos, 1, {"air"}) -end - - --- Detect nearby extinguishing nodes - -function fire.flame_should_extinguish(pos) - return minetest.find_node_near(pos, 1, {"group:puts_out_fire"}) -end - - -- Extinguish all flames quickly with water, snow, ice minetest.register_abm({ @@ -239,31 +223,27 @@ else catch_up = false, action = function(p0, node, _, _) -- If there is water or stuff like that around node, don't ignite - if fire.flame_should_extinguish(p0) then + if minetest.find_node_near(p0, 1, {"group:puts_out_fire"}) then return end - local p = fire.find_pos_for_flame_around(p0) + local p = minetest.find_node_near(p0, 1, {"air"}) if p then minetest.set_node(p, {name = "fire:basic_flame"}) end end, }) - -- Remove basic flames and flammable nodes + -- Remove flammable nodes minetest.register_abm({ nodenames = {"fire:basic_flame"}, + neighbors = "group:flammable", interval = 5, - chance = 6, + chance = 18, catch_up = false, action = function(p0, node, _, _) - -- If there are no flammable nodes around flame, remove flame local p = minetest.find_node_near(p0, 1, {"group:flammable"}) - if not p then - minetest.remove_node(p0) - return - end - if math.random(1, 3) == 1 then + if p then -- remove flammable nodes around flame local node = minetest.get_node(p) local def = minetest.registered_nodes[node.name]