diff options
author | Jeija <norrepli@gmail.com> | 2016-07-25 10:01:43 +0200 |
---|---|---|
committer | Jeija <norrepli@gmail.com> | 2016-07-25 10:01:43 +0200 |
commit | 7c7595fd7dea6bc569086c544c74682552824e41 (patch) | |
tree | 11bd6867c37f697a47e7df25c7c6651accf92b05 | |
parent | acd41b57733bee4c61729f4ec1ce1742402b59d8 (diff) | |
download | mesecons-7c7595fd7dea6bc569086c544c74682552824e41.tar mesecons-7c7595fd7dea6bc569086c544c74682552824e41.tar.gz mesecons-7c7595fd7dea6bc569086c544c74682552824e41.tar.bz2 mesecons-7c7595fd7dea6bc569086c544c74682552824e41.tar.xz mesecons-7c7595fd7dea6bc569086c544c74682552824e41.zip |
Fix #276: Fix bugs in block forceloading in turnon / turnoff
Thanks to @Hawk777 for reporting this problem
-rw-r--r-- | mesecons/internal.lua | 84 |
1 files changed, 53 insertions, 31 deletions
diff --git a/mesecons/internal.lua b/mesecons/internal.lua index d479852..d9c5886 100644 --- a/mesecons/internal.lua +++ b/mesecons/internal.lua @@ -76,7 +76,7 @@ function mesecon.get_conductor(nodename) end end -function mesecon.get_any_outputrules (node) +function mesecon.get_any_outputrules(node) if not node then return nil end if mesecon.is_conductor(node.name) then @@ -86,7 +86,7 @@ function mesecon.get_any_outputrules (node) end end -function mesecon.get_any_inputrules (node) +function mesecon.get_any_inputrules(node) if not node then return nil end if mesecon.is_conductor(node.name) then @@ -96,7 +96,7 @@ function mesecon.get_any_inputrules (node) end end -function mesecon.get_any_rules (node) +function mesecon.get_any_rules(node) return mesecon.mergetable(mesecon.get_any_inputrules(node) or {}, mesecon.get_any_outputrules(node) or {}) end @@ -381,28 +381,39 @@ function mesecon.turnon(pos, link) -- area not loaded, postpone action if not node then - mesecon.queue:add_action(f.pos, "turnon", {link}, nil, true) + mesecon.queue:add_action(f.pos, "turnon", {f.link}, nil, true) elseif mesecon.is_conductor_off(node, f.link) then local rules = mesecon.conductor_get_rules(node) - minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link), - param2 = node.param2}) + -- Success: If false, at least one neighboring node is unloaded, + -- postpone turning on action + local success = true + local neighborlinks = {} - -- call turnon on neighbors: normal rules + -- call turnon on neighbors for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) - -- area not loaded, postpone action + -- Neighboring node not loaded, postpone turning on current node + -- since we can't even know if neighboring node has matching rules if not mesecon.get_node_force(np) then - mesecon.queue:add_action(np, "turnon", {rulename}, - nil, true) + success = false + break else - local links = mesecon.rules_link_rule_all(f.pos, r) - for _, l in ipairs(links) do - table.insert(frontiers, {pos = np, link = l}) - end + neighborlinks[minetest.hash_node_position(np)] = mesecon.rules_link_rule_all(f.pos, r) end end + + if success then + minetest.swap_node(f.pos, {name = mesecon.get_conductor_on(node, f.link), + param2 = node.param2}) + + for npos, l in pairs(neighborlinks) do + table.insert(frontiers, {pos = minetest.get_position_from_hash(npos), link = l}) + end + else + mesecon.queue:add_action(f.pos, "turnon", {f.link}, nil, true) + end elseif mesecon.is_effector(node.name) then mesecon.changesignal(f.pos, node, f.link, mesecon.state.on, depth) if mesecon.is_effector_off(node.name) then @@ -413,7 +424,7 @@ function mesecon.turnon(pos, link) end end -mesecon.queue:add_function("turnon", function (pos, rulename, recdepth) +mesecon.queue:add_function("turnon", function(pos, rulename, recdepth) mesecon.turnon(pos, rulename, recdepth) end) @@ -427,27 +438,38 @@ function mesecon.turnoff(pos, link) -- area not loaded, postpone action if not node then - mesecon.queue:add_action(f.pos, "turnoff", {link}, nil, true) + mesecon.queue:add_action(f.pos, "turnoff", {f.link}, nil, true) elseif mesecon.is_conductor_on(node, f.link) then local rules = mesecon.conductor_get_rules(node) - minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link), - param2 = node.param2}) + -- Success: If false, at least one neighboring node is unloaded, + -- postpone turning on action + local success = true + local neighborlinks = {} - -- call turnoff on neighbors: normal rules + -- call turnoff on neighbors for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do local np = vector.add(f.pos, r) - -- area not loaded, postpone action + -- Neighboring node not loaded, postpone turning off current node + -- since we can't even know if neighboring node has matching rules if not mesecon.get_node_force(np) then - mesecon.queue:add_action(np, "turnoff", {rulename}, - nil, true) + success = false + break else - local links = mesecon.rules_link_rule_all(f.pos, r) - for _, l in ipairs(links) do - table.insert(frontiers, {pos = np, link = l}) - end + neighborlinks[minetest.hash_node_position(np)] = mesecon.rules_link_rule_all(f.pos, r) + end + end + + if success then + minetest.swap_node(f.pos, {name = mesecon.get_conductor_off(node, f.link), + param2 = node.param2}) + + for npos, l in pairs(neighborlinks) do + table.insert(frontiers, {pos = minetest.get_position_from_hash(npos), link = l}) end + else + mesecon.queue:add_action(f.pos, "turnoff", {f.link}, nil, true) end elseif mesecon.is_effector(node.name) then mesecon.changesignal(f.pos, node, f.link, mesecon.state.off, depth) @@ -459,7 +481,7 @@ function mesecon.turnoff(pos, link) end end -mesecon.queue:add_function("turnoff", function (pos, rulename, recdepth) +mesecon.queue:add_function("turnoff", function(pos, rulename, recdepth) mesecon.turnoff(pos, rulename, recdepth) end) @@ -523,8 +545,8 @@ function mesecon.rules_link(output, input, dug_outputrules) --output/input are p local outputnode = mesecon.get_node_force(output) local inputnode = mesecon.get_node_force(input) - local outputrules = dug_outputrules or mesecon.get_any_outputrules (outputnode) - local inputrules = mesecon.get_any_inputrules (inputnode) + local outputrules = dug_outputrules or mesecon.get_any_outputrules(outputnode) + local inputrules = mesecon.get_any_inputrules(inputnode) if not outputrules or not inputrules then return end @@ -547,7 +569,7 @@ end function mesecon.rules_link_rule_all(output, rule) local input = vector.add(output, rule) local inputnode = mesecon.get_node_force(input) - local inputrules = mesecon.get_any_inputrules (inputnode) + local inputrules = mesecon.get_any_inputrules(inputnode) if not inputrules then return {} end @@ -567,7 +589,7 @@ function mesecon.rules_link_rule_all_inverted(input, rule) --local irule = mesecon.invertRule(rule) local output = vector.add(input, rule) local outputnode = mesecon.get_node_force(output) - local outputrules = mesecon.get_any_outputrules (outputnode) + local outputrules = mesecon.get_any_outputrules(outputnode) if not outputrules then return {} end |