forked from luanti-org/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:
		| @@ -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] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user