forked from minetest/minetest_game
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.
This commit is contained in:
parent
e0cb3fce02
commit
d61803b65f
|
@ -28,14 +28,24 @@ minetest.register_node("fire:basic_flame", {
|
||||||
sunlight_propagates = true,
|
sunlight_propagates = true,
|
||||||
damage_per_second = 4,
|
damage_per_second = 4,
|
||||||
groups = {igniter = 2, dig_immediate = 3, not_in_creative_inventory = 1},
|
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 = "",
|
drop = "",
|
||||||
|
|
||||||
on_construct = function(pos)
|
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,
|
end,
|
||||||
|
|
||||||
on_destruct = function(pos)
|
on_destruct = function(pos)
|
||||||
minetest.after(0, fire.on_flame_remove_at, pos)
|
minetest.after(0, fire.update_sounds_around, pos)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_blast = function()
|
on_blast = function()
|
||||||
|
@ -169,32 +179,6 @@ function fire.update_sounds_around(pos)
|
||||||
end
|
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
|
-- Extinguish all flames quickly with water, snow, ice
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
|
@ -239,31 +223,27 @@ else
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
action = function(p0, node, _, _)
|
action = function(p0, node, _, _)
|
||||||
-- If there is water or stuff like that around node, don't ignite
|
-- 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
|
return
|
||||||
end
|
end
|
||||||
local p = fire.find_pos_for_flame_around(p0)
|
local p = minetest.find_node_near(p0, 1, {"air"})
|
||||||
if p then
|
if p then
|
||||||
minetest.set_node(p, {name = "fire:basic_flame"})
|
minetest.set_node(p, {name = "fire:basic_flame"})
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Remove basic flames and flammable nodes
|
-- Remove flammable nodes
|
||||||
|
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
nodenames = {"fire:basic_flame"},
|
nodenames = {"fire:basic_flame"},
|
||||||
|
neighbors = "group:flammable",
|
||||||
interval = 5,
|
interval = 5,
|
||||||
chance = 6,
|
chance = 18,
|
||||||
catch_up = false,
|
catch_up = false,
|
||||||
action = function(p0, node, _, _)
|
action = function(p0, node, _, _)
|
||||||
-- If there are no flammable nodes around flame, remove flame
|
|
||||||
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
|
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
|
||||||
if not p then
|
if p then
|
||||||
minetest.remove_node(p0)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if math.random(1, 3) == 1 then
|
|
||||||
-- remove flammable nodes around flame
|
-- remove flammable nodes around flame
|
||||||
local node = minetest.get_node(p)
|
local node = minetest.get_node(p)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user