forked from minetest-mods/mesecons
		
	Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		@@ -368,11 +368,66 @@ function mesecon.is_power_off(pos, rulename)
 | 
			
		||||
	return false
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- The set of conductor states which require light updates when they change.
 | 
			
		||||
local light_update_conductors
 | 
			
		||||
 | 
			
		||||
-- Calculate the contents of the above set if they have not been calculated.
 | 
			
		||||
-- This must be called before get_update_light_conductor.
 | 
			
		||||
local function find_light_update_conductors()
 | 
			
		||||
	-- The expensive calculation is only done the first time.
 | 
			
		||||
	if light_update_conductors then return end
 | 
			
		||||
 | 
			
		||||
	light_update_conductors = {}
 | 
			
		||||
 | 
			
		||||
	-- Find conductors whose lighting characteristics change depending on their state.
 | 
			
		||||
	local checked = {}
 | 
			
		||||
	for name, def in pairs(minetest.registered_nodes) do
 | 
			
		||||
		local conductor = mesecon.get_conductor(name)
 | 
			
		||||
		if conductor and not checked[name] then
 | 
			
		||||
			-- Find the other states of the conductor besides the current one.
 | 
			
		||||
			local other_states
 | 
			
		||||
			if conductor.onstate then
 | 
			
		||||
				other_states = {conductor.onstate}
 | 
			
		||||
			elseif conductor.offstate then
 | 
			
		||||
				other_states = {conductor.offstate}
 | 
			
		||||
			else
 | 
			
		||||
				other_states = conductor.states
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			-- Check the conductor. Other states are marked as checked.
 | 
			
		||||
			for _, other_state in ipairs(other_states) do
 | 
			
		||||
				local other_def = minetest.registered_nodes[other_state]
 | 
			
		||||
				if (def.paramtype == "light") ~= (other_def.paramtype == "light")
 | 
			
		||||
				or def.sunlight_propagates ~= other_def.sunlight_propagates
 | 
			
		||||
				or def.light_source ~= other_def.light_source then
 | 
			
		||||
					-- The light characteristics change depending on the state.
 | 
			
		||||
					-- The states are added to the set.
 | 
			
		||||
					light_update_conductors[name] = true
 | 
			
		||||
					for _, other_state in ipairs(other_states) do
 | 
			
		||||
						light_update_conductors[other_state] = true
 | 
			
		||||
						checked[other_state] = true
 | 
			
		||||
					end
 | 
			
		||||
					break
 | 
			
		||||
				end
 | 
			
		||||
				checked[other_state] = true
 | 
			
		||||
			end
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- This is the callback for swap_node_force in turnon and turnoff. It determines
 | 
			
		||||
-- whether a conductor node necessitates a lighting update.
 | 
			
		||||
local function get_update_light_conductor(pos, name)
 | 
			
		||||
	return light_update_conductors[name] ~= nil
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Turn off an equipotential section starting at `pos`, which outputs in the direction of `link`.
 | 
			
		||||
-- Breadth-first search. Map is abstracted away in a voxelmanip.
 | 
			
		||||
-- Follow all all conductor paths replacing conductors that were already
 | 
			
		||||
-- looked at, activating / changing all effectors along the way.
 | 
			
		||||
function mesecon.turnon(pos, link)
 | 
			
		||||
	find_light_update_conductors()
 | 
			
		||||
 | 
			
		||||
	local frontiers = fifo_queue.new()
 | 
			
		||||
	frontiers:add({pos = pos, link = link})
 | 
			
		||||
	local pos_can_be_skipped = {}
 | 
			
		||||
@@ -398,7 +453,7 @@ function mesecon.turnon(pos, link)
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link))
 | 
			
		||||
				mesecon.swap_node_force(f.pos, mesecon.get_conductor_on(node, f.link), get_update_light_conductor)
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			-- Only conductors with flat rules can be reliably skipped later
 | 
			
		||||
@@ -434,6 +489,8 @@ end
 | 
			
		||||
--	depth = indicates order in which signals wire fired, higher is later
 | 
			
		||||
-- }
 | 
			
		||||
function mesecon.turnoff(pos, link)
 | 
			
		||||
	find_light_update_conductors()
 | 
			
		||||
 | 
			
		||||
	local frontiers = fifo_queue.new()
 | 
			
		||||
	frontiers:add({pos = pos, link = link})
 | 
			
		||||
	local signals = {}
 | 
			
		||||
@@ -470,7 +527,7 @@ function mesecon.turnoff(pos, link)
 | 
			
		||||
					end
 | 
			
		||||
				end
 | 
			
		||||
 | 
			
		||||
				mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link))
 | 
			
		||||
				mesecon.swap_node_force(f.pos, mesecon.get_conductor_off(node, f.link), get_update_light_conductor)
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			-- Only conductors with flat rules can be reliably skipped later
 | 
			
		||||
 
 | 
			
		||||
@@ -343,7 +343,7 @@ function mesecon.vm_commit()
 | 
			
		||||
		if tbl.dirty then
 | 
			
		||||
			local vm = tbl.vm
 | 
			
		||||
			vm:set_data(tbl.data)
 | 
			
		||||
			vm:write_to_map()
 | 
			
		||||
			vm:write_to_map(tbl.update_light)
 | 
			
		||||
			vm:update_map()
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -364,7 +364,7 @@ local function vm_get_or_create_entry(pos)
 | 
			
		||||
		local vm = minetest.get_voxel_manip(pos, pos)
 | 
			
		||||
		local min_pos, max_pos = vm:get_emerged_area()
 | 
			
		||||
		local va = VoxelArea:new{MinEdge = min_pos, MaxEdge = max_pos}
 | 
			
		||||
		tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false}
 | 
			
		||||
		tbl = {vm = vm, va = va, data = vm:get_data(), param1 = vm:get_light_data(), param2 = vm:get_param2_data(), dirty = false, update_light = false}
 | 
			
		||||
		vm_cache[hash] = tbl
 | 
			
		||||
	end
 | 
			
		||||
	return tbl
 | 
			
		||||
@@ -388,8 +388,11 @@ end
 | 
			
		||||
-- Sets a node’s name during a VoxelManipulator-based transaction.
 | 
			
		||||
--
 | 
			
		||||
-- Existing param1, param2, and metadata are left alone.
 | 
			
		||||
function mesecon.vm_swap_node(pos, name)
 | 
			
		||||
--
 | 
			
		||||
-- See mesecon.swap_node_force for documentation about get_update_light.
 | 
			
		||||
function mesecon.vm_swap_node(pos, name, get_update_light)
 | 
			
		||||
	local tbl = vm_get_or_create_entry(pos)
 | 
			
		||||
	tbl.update_light = tbl.update_light or (get_update_light == nil or get_update_light(pos, name))
 | 
			
		||||
	local index = tbl.va:indexp(pos)
 | 
			
		||||
	tbl.data[index] = minetest.get_content_id(name)
 | 
			
		||||
	tbl.dirty = true
 | 
			
		||||
@@ -423,13 +426,15 @@ end
 | 
			
		||||
-- Outside a VM transaction, if the mapblock is not loaded, it is pulled into
 | 
			
		||||
-- the server’s main map data cache and then accessed from there.
 | 
			
		||||
--
 | 
			
		||||
-- Inside a VM transaction, the transaction’s VM cache is used.
 | 
			
		||||
-- Inside a VM transaction, the transaction’s VM cache is used. If a third
 | 
			
		||||
-- argument is supplied, it may be called. If it returns false, the swap does
 | 
			
		||||
-- not necessitate a lighting update.
 | 
			
		||||
--
 | 
			
		||||
-- This function can only be used to change the node’s name, not its parameters
 | 
			
		||||
-- or metadata.
 | 
			
		||||
function mesecon.swap_node_force(pos, name)
 | 
			
		||||
function mesecon.swap_node_force(pos, name, get_update_light)
 | 
			
		||||
	if vm_cache then
 | 
			
		||||
		return mesecon.vm_swap_node(pos, name)
 | 
			
		||||
		return mesecon.vm_swap_node(pos, name, get_update_light)
 | 
			
		||||
	else
 | 
			
		||||
		-- This serves to both ensure the mapblock is loaded and also hand us
 | 
			
		||||
		-- the old node table so we can preserve param2.
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user