Limit fire spread by making fires age and less likely to spread the longer they have been burning

This commit is contained in:
teknomunk 2024-05-18 11:35:04 +00:00
parent d264ba70d8
commit caeebcec60
1 changed files with 56 additions and 1 deletions

View File

@ -50,6 +50,28 @@ local function has_flammable(pos)
end end
end end
end end
local all_adjacents = {}
for x = 0,1 do
for y = 0,1 do
for z = 0,1 do
all_adjacents[#all_adjacents+1] = vector.new(x*2-1, y*2-1, z*2-1)
end
end
end
local function get_adjacent_fire_age(pos)
local lowest_age = nil
for k,v in pairs(all_adjacents) do
local p = vector.add(pos, v)
local node = minetest.get_node_or_nil(p)
if node and minetest.get_item_group(node.name, "fire") ~= 0 then
if not lowest_age or node.param2 < lowest_age then
lowest_age = node.param2
end
end
end
return lowest_age
end
local smoke_pdef = { local smoke_pdef = {
amount = 0.009, amount = 0.009,
@ -91,6 +113,26 @@ else
end end
local function spawn_fire(pos, age) local function spawn_fire(pos, age)
if not age then
-- Get adjacent age
local adjacent_age = get_adjacent_fire_age(pos)
-- Don't create new fire if we can't find adjacent fire from this position
if not adjacent_age then return end
age = math.random(1,5) + adjacent_age
end
if age <= 1 then
print("new flash point at "..vector.to_string(pos).." age="..tostring(age))
print(debug.traceback())
end
-- Limit fire spread
local probability = math.pow(10,-1.176e-2 * age) -- exponential constant is such that at age=255, p=0.1%
if math.random(65536)/65536 >= probability then
return
end
set_node(pos, {name="mcl_fire:fire", param2 = age}) set_node(pos, {name="mcl_fire:fire", param2 = age})
minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) minetest.check_single_for_falling({x=pos.x, y=pos.y+1, z=pos.z})
end end
@ -368,8 +410,21 @@ else -- Fire enabled
action = function(pos) action = function(pos)
local p = get_ignitable(pos) local p = get_ignitable(pos)
if p then if p then
spawn_fire(p) local node = minetest.get_node(pos)
local age = node.param2
-- Spawn new fire with an age based on this node's age
spawn_fire(p, age+math.random(3,7))
shuffle_table(adjacents) shuffle_table(adjacents)
-- Age the source fire
age = age + math.random(2,5)
node.param2 = age
if age >= 255 then
node.name = "air"
node.param2 = 0
end
minetest.set_node(pos, node)
end end
end end
}) })