forked from Mirrorlandia_minetest/mesecons
Use FIFO queue for mvps (#599)
This commit is contained in:
parent
21ac966ee2
commit
f4070d3e64
@ -46,7 +46,8 @@
|
|||||||
-- mesecon.rotate_rules_down(rules)
|
-- mesecon.rotate_rules_down(rules)
|
||||||
-- These functions return rules that have been rotated in the specific direction
|
-- These functions return rules that have been rotated in the specific direction
|
||||||
|
|
||||||
local fifo_queue = dofile(minetest.get_modpath("mesecons").."/fifo_queue.lua")
|
-- See fifo_queue.lua for documentation.
|
||||||
|
mesecon.fifo_queue = dofile(minetest.get_modpath("mesecons").."/fifo_queue.lua")
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
function mesecon.get_effector(nodename)
|
function mesecon.get_effector(nodename)
|
||||||
@ -421,7 +422,7 @@ end
|
|||||||
function mesecon.turnon(pos, link)
|
function mesecon.turnon(pos, link)
|
||||||
find_light_update_conductors()
|
find_light_update_conductors()
|
||||||
|
|
||||||
local frontiers = fifo_queue.new()
|
local frontiers = mesecon.fifo_queue.new()
|
||||||
frontiers:add({pos = pos, link = link})
|
frontiers:add({pos = pos, link = link})
|
||||||
local pos_can_be_skipped = {}
|
local pos_can_be_skipped = {}
|
||||||
|
|
||||||
@ -484,7 +485,7 @@ end
|
|||||||
function mesecon.turnoff(pos, link)
|
function mesecon.turnoff(pos, link)
|
||||||
find_light_update_conductors()
|
find_light_update_conductors()
|
||||||
|
|
||||||
local frontiers = fifo_queue.new()
|
local frontiers = mesecon.fifo_queue.new()
|
||||||
frontiers:add({pos = pos, link = link})
|
frontiers:add({pos = pos, link = link})
|
||||||
local signals = {}
|
local signals = {}
|
||||||
local pos_can_be_skipped = {}
|
local pos_can_be_skipped = {}
|
||||||
|
@ -63,28 +63,31 @@ end
|
|||||||
function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
|
function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
|
||||||
-- determine the number of nodes to be pushed
|
-- determine the number of nodes to be pushed
|
||||||
local nodes = {}
|
local nodes = {}
|
||||||
local frontiers = {pos}
|
local pos_set = {}
|
||||||
|
local frontiers = mesecon.fifo_queue.new()
|
||||||
|
frontiers:add(vector.new(pos))
|
||||||
|
|
||||||
while #frontiers > 0 do
|
for np in frontiers:iter() do
|
||||||
local np = frontiers[1]
|
local np_hash = minetest.hash_node_position(np)
|
||||||
local nn = minetest.get_node(np)
|
local nn = not pos_set[np_hash] and minetest.get_node(np)
|
||||||
|
if nn and not node_replaceable(nn.name) then
|
||||||
if not node_replaceable(nn.name) then
|
pos_set[np_hash] = true
|
||||||
table.insert(nodes, {node = nn, pos = np})
|
table.insert(nodes, {node = nn, pos = np})
|
||||||
if #nodes > maximum then return nil end
|
if #nodes > maximum then return nil end
|
||||||
|
|
||||||
-- add connected nodes to frontiers, connected is a vector list
|
-- add connected nodes to frontiers
|
||||||
-- the vectors must be absolute positions
|
|
||||||
local connected = {}
|
|
||||||
if minetest.registered_nodes[nn.name]
|
if minetest.registered_nodes[nn.name]
|
||||||
and minetest.registered_nodes[nn.name].mvps_sticky then
|
and minetest.registered_nodes[nn.name].mvps_sticky then
|
||||||
connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
|
local connected = minetest.registered_nodes[nn.name].mvps_sticky(np, nn)
|
||||||
|
for _, cp in ipairs(connected) do
|
||||||
|
frontiers:add(cp)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert(connected, vector.add(np, dir))
|
frontiers:add(vector.add(np, dir))
|
||||||
|
|
||||||
-- If adjacent node is sticky block and connects add that
|
-- If adjacent node is sticky block and connects add that
|
||||||
-- position to the connected table
|
-- position
|
||||||
for _, r in ipairs(mesecon.rules.alldirs) do
|
for _, r in ipairs(mesecon.rules.alldirs) do
|
||||||
local adjpos = vector.add(np, r)
|
local adjpos = vector.add(np, r)
|
||||||
local adjnode = minetest.get_node(adjpos)
|
local adjnode = minetest.get_node(adjpos)
|
||||||
@ -96,36 +99,16 @@ function mesecon.mvps_get_stack(pos, dir, maximum, all_pull_sticky)
|
|||||||
-- connects to this position?
|
-- connects to this position?
|
||||||
for _, link in ipairs(sticksto) do
|
for _, link in ipairs(sticksto) do
|
||||||
if vector.equals(link, np) then
|
if vector.equals(link, np) then
|
||||||
table.insert(connected, adjpos)
|
frontiers:add(adjpos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if all_pull_sticky then
|
if all_pull_sticky then
|
||||||
table.insert(connected, vector.subtract(np, dir))
|
frontiers:add(vector.subtract(np, dir))
|
||||||
end
|
|
||||||
|
|
||||||
-- Make sure there are no duplicates in frontiers / nodes before
|
|
||||||
-- adding nodes in "connected" to frontiers
|
|
||||||
for _, cp in ipairs(connected) do
|
|
||||||
local duplicate = false
|
|
||||||
for _, rp in ipairs(nodes) do
|
|
||||||
if vector.equals(cp, rp.pos) then
|
|
||||||
duplicate = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, fp in ipairs(frontiers) do
|
|
||||||
if vector.equals(cp, fp) then
|
|
||||||
duplicate = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if not duplicate then
|
|
||||||
table.insert(frontiers, cp)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
table.remove(frontiers, 1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return nodes
|
return nodes
|
||||||
|
Loading…
Reference in New Issue
Block a user