forked from VoxeLibre/VoxeLibre
Merge remote-tracking branch 'origin/master' into mineclone5
This commit is contained in:
commit
bc16c33dde
|
@ -47,28 +47,35 @@
|
||||||
-- 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 equals = vector.equals
|
||||||
|
local get_node_force = mesecon.get_node_force
|
||||||
|
local receptor_get_rules = mesecon.receptor_get_rules
|
||||||
|
local invertRule = mesecon.invertRule
|
||||||
|
local copy, insert = table.copy, table.insert
|
||||||
|
local registered_nodes = minetest.registered_nodes
|
||||||
|
|
||||||
-- General
|
-- General
|
||||||
function mesecon.get_effector(nodename)
|
function mesecon.get_effector(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.effector then
|
and registered_nodes[nodename].mesecons.effector then
|
||||||
return minetest.registered_nodes[nodename].mesecons.effector
|
return registered_nodes[nodename].mesecons.effector
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_receptor(nodename)
|
function mesecon.get_receptor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.receptor then
|
and registered_nodes[nodename].mesecons.receptor then
|
||||||
return minetest.registered_nodes[nodename].mesecons.receptor
|
return registered_nodes[nodename].mesecons.receptor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.get_conductor(nodename)
|
function mesecon.get_conductor(nodename)
|
||||||
if minetest.registered_nodes[nodename]
|
if registered_nodes[nodename]
|
||||||
and minetest.registered_nodes[nodename].mesecons
|
and registered_nodes[nodename].mesecons
|
||||||
and minetest.registered_nodes[nodename].mesecons.conductor then
|
and registered_nodes[nodename].mesecons.conductor then
|
||||||
return minetest.registered_nodes[nodename].mesecons.conductor
|
return registered_nodes[nodename].mesecons.conductor
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -103,13 +110,14 @@ end
|
||||||
|
|
||||||
-- Receptors
|
-- Receptors
|
||||||
-- Nodes that can power mesecons
|
-- Nodes that can power mesecons
|
||||||
function mesecon.is_receptor_on(nodename)
|
local function is_receptor_on(nodename)
|
||||||
local receptor = mesecon.get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
if receptor and receptor.state == mesecon.state.on then
|
if receptor and receptor.state == mesecon.state.on then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
mesecon.is_receptor_on = is_receptor_on
|
||||||
|
|
||||||
function mesecon.is_receptor_off(nodename)
|
function mesecon.is_receptor_off(nodename)
|
||||||
local receptor = mesecon.get_receptor(nodename)
|
local receptor = mesecon.get_receptor(nodename)
|
||||||
|
@ -186,7 +194,7 @@ end
|
||||||
|
|
||||||
-- Activation:
|
-- Activation:
|
||||||
mesecon.queue:add_function("activate", function (pos, rulename)
|
mesecon.queue:add_function("activate", function (pos, rulename)
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
if not node then return end
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -198,7 +206,7 @@ end)
|
||||||
|
|
||||||
function mesecon.activate(pos, node, rulename, depth)
|
function mesecon.activate(pos, node, rulename, depth)
|
||||||
if rulename == nil then
|
if rulename == nil then
|
||||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||||
mesecon.activate(pos, node, rule, depth + 1)
|
mesecon.activate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -209,7 +217,7 @@ end
|
||||||
|
|
||||||
-- Deactivation
|
-- Deactivation
|
||||||
mesecon.queue:add_function("deactivate", function (pos, rulename)
|
mesecon.queue:add_function("deactivate", function (pos, rulename)
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
if not node then return end
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -221,7 +229,7 @@ end)
|
||||||
|
|
||||||
function mesecon.deactivate(pos, node, rulename, depth)
|
function mesecon.deactivate(pos, node, rulename, depth)
|
||||||
if rulename == nil then
|
if rulename == nil then
|
||||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||||
mesecon.deactivate(pos, node, rule, depth + 1)
|
mesecon.deactivate(pos, node, rule, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -232,7 +240,7 @@ end
|
||||||
|
|
||||||
-- Change
|
-- Change
|
||||||
mesecon.queue:add_function("change", function (pos, rulename, changetype)
|
mesecon.queue:add_function("change", function (pos, rulename, changetype)
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
if not node then return end
|
if not node then return end
|
||||||
|
|
||||||
local effector = mesecon.get_effector(node.name)
|
local effector = mesecon.get_effector(node.name)
|
||||||
|
@ -244,7 +252,7 @@ end)
|
||||||
|
|
||||||
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
||||||
if rulename == nil then
|
if rulename == nil then
|
||||||
for _,rule in ipairs(mesecon.effector_get_rules(node)) do
|
for _,rule in pairs(mesecon.effector_get_rules(node)) do
|
||||||
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
|
mesecon.changesignal(pos, node, rule, newstate, depth + 1)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
@ -356,15 +364,15 @@ end
|
||||||
-- some more general high-level stuff
|
-- some more general high-level stuff
|
||||||
|
|
||||||
function mesecon.is_power_on(pos, rulename)
|
function mesecon.is_power_on(pos, rulename)
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
if node and (mesecon.is_conductor_on(node, rulename) or mesecon.is_receptor_on(node.name)) then
|
if node and (mesecon.is_conductor_on(node, rulename) or is_receptor_on(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function mesecon.is_power_off(pos, rulename)
|
function mesecon.is_power_off(pos, rulename)
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
|
if node and (mesecon.is_conductor_off(node, rulename) or mesecon.is_receptor_off(node.name)) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -381,7 +389,7 @@ function mesecon.turnon(pos, link)
|
||||||
local depth = 1
|
local depth = 1
|
||||||
while frontiers[1] do
|
while frontiers[1] do
|
||||||
local f = table.remove(frontiers, 1)
|
local f = table.remove(frontiers, 1)
|
||||||
local node = mesecon.get_node_force(f.pos)
|
local node = get_node_force(f.pos)
|
||||||
|
|
||||||
if not node then
|
if not node then
|
||||||
-- Area does not exist; do nothing
|
-- Area does not exist; do nothing
|
||||||
|
@ -389,10 +397,10 @@ function mesecon.turnon(pos, link)
|
||||||
local rules = mesecon.conductor_get_rules(node)
|
local rules = mesecon.conductor_get_rules(node)
|
||||||
|
|
||||||
-- Call turnon on neighbors
|
-- Call turnon on neighbors
|
||||||
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||||
local np = vector.add(f.pos, r)
|
local np = vector.add(f.pos, r)
|
||||||
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
table.insert(frontiers, {pos = np, link = l})
|
insert(frontiers, {pos = np, link = l})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -406,12 +414,12 @@ function mesecon.turnon(pos, link)
|
||||||
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
||||||
-- Call turnon on neighbors
|
-- Call turnon on neighbors
|
||||||
-- Warning: A LOT of nodes need to be looked at for this to work
|
-- Warning: A LOT of nodes need to be looked at for this to work
|
||||||
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
||||||
local np = vector.add(f.pos, r)
|
local np = vector.add(f.pos, r)
|
||||||
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
local nlink = table.copy(l)
|
local nlink = copy(l)
|
||||||
nlink.spread = false
|
nlink.spread = false
|
||||||
table.insert(frontiers, {pos = np, link = nlink})
|
insert(frontiers, {pos = np, link = nlink})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -443,33 +451,33 @@ function mesecon.turnoff(pos, link)
|
||||||
local depth = 1
|
local depth = 1
|
||||||
while frontiers[1] do
|
while frontiers[1] do
|
||||||
local f = table.remove(frontiers, 1)
|
local f = table.remove(frontiers, 1)
|
||||||
local node = mesecon.get_node_force(f.pos)
|
local node = get_node_force(f.pos)
|
||||||
|
|
||||||
if not node then
|
if not node then
|
||||||
-- No-op
|
-- No-op
|
||||||
elseif mesecon.is_conductor_on(node, f.link) then
|
elseif mesecon.is_conductor_on(node, f.link) then
|
||||||
local rules = mesecon.conductor_get_rules(node)
|
local rules = mesecon.conductor_get_rules(node)
|
||||||
for _, r in ipairs(mesecon.rule2meta(f.link, rules)) do
|
for _, r in pairs(mesecon.rule2meta(f.link, rules)) do
|
||||||
local np = vector.add(f.pos, r)
|
local np = vector.add(f.pos, r)
|
||||||
|
|
||||||
-- Check if an onstate receptor is connected. If that is the case,
|
-- Check if an onstate receptor is connected. If that is the case,
|
||||||
-- abort this turnoff process by returning false. `receptor_off` will
|
-- abort this turnoff process by returning false. `receptor_off` will
|
||||||
-- discard all the changes that we made in the voxelmanip:
|
-- discard all the changes that we made in the voxelmanip:
|
||||||
for _, l in ipairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
|
for _, l in pairs(mesecon.rules_link_rule_all_inverted(f.pos, r)) do
|
||||||
if mesecon.is_receptor_on(mesecon.get_node_force(np).name) then
|
if is_receptor_on(get_node_force(np).name) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Call turnoff on neighbors
|
-- Call turnoff on neighbors
|
||||||
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in pairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
||||||
table.insert(frontiers, {pos = np, link = l})
|
insert(frontiers, {pos = np, link = l})
|
||||||
end
|
end
|
||||||
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))
|
||||||
elseif mesecon.is_effector(node.name) then
|
elseif mesecon.is_effector(node.name) then
|
||||||
table.insert(signals, {
|
insert(signals, {
|
||||||
pos = f.pos,
|
pos = f.pos,
|
||||||
node = node,
|
node = node,
|
||||||
link = f.link,
|
link = f.link,
|
||||||
|
@ -480,27 +488,22 @@ function mesecon.turnoff(pos, link)
|
||||||
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
if node and f.link.spread and minetest.get_item_group(node.name, "opaque") == 1 then
|
||||||
-- Call turnoff on neighbors
|
-- Call turnoff on neighbors
|
||||||
-- Warning: A LOT of nodes need to be looked at for this to work
|
-- Warning: A LOT of nodes need to be looked at for this to work
|
||||||
for _, r in ipairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
local fpos = f.pos
|
||||||
local np = vector.add(f.pos, r)
|
for _, r in pairs(mesecon.rule2meta(f.link, mesecon.rules.mcl_alldirs_spread)) do
|
||||||
local n = mesecon.get_node_force(np)
|
local np = {x=fpos.x+r.x, y=fpos.y+r.y, z=fpos.z+r.z}
|
||||||
|
local n = get_node_force(np)
|
||||||
if not n then
|
if n and is_receptor_on(n.name) then
|
||||||
mcl_explosions.explode(f.pos, 10)
|
local receptorrules = receptor_get_rules(n)
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if mesecon.is_receptor_on(n.name) then
|
|
||||||
local receptorrules = mesecon.receptor_get_rules(n)
|
|
||||||
for _, rr in pairs(receptorrules) do
|
for _, rr in pairs(receptorrules) do
|
||||||
if rr.spread and vector.equals(mesecon.invertRule(rr), r) then
|
if rr.spread and equals(invertRule(rr), r) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _, l in ipairs(mesecon.rules_link_rule_all(f.pos, r)) do
|
for _, l in pairs(mesecon.rules_link_rule_all(fpos, r)) do
|
||||||
local nlink = table.copy(l)
|
local nlink = copy(l)
|
||||||
nlink.spread = false
|
nlink.spread = false
|
||||||
table.insert(frontiers, {pos = np, link = nlink})
|
insert(frontiers, {pos = np, link = nlink})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -508,7 +511,7 @@ function mesecon.turnoff(pos, link)
|
||||||
depth = depth + 1
|
depth = depth + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, sig in ipairs(signals) do
|
for _, sig in pairs(signals) do
|
||||||
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
mesecon.changesignal(sig.pos, sig.node, sig.link, mesecon.state.off, sig.depth)
|
||||||
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
if mesecon.is_effector_on(sig.node.name) and not mesecon.is_powered(sig.pos) then
|
||||||
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
mesecon.deactivate(sig.pos, sig.node, sig.link, sig.depth)
|
||||||
|
@ -522,19 +525,19 @@ end
|
||||||
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
|
-- outputnode (receptor or conductor) at position `output` and has an output in direction `rule`
|
||||||
function mesecon.rules_link_rule_all(output, rule)
|
function mesecon.rules_link_rule_all(output, rule)
|
||||||
local input = vector.add(output, rule)
|
local input = vector.add(output, rule)
|
||||||
local inputnode = mesecon.get_node_force(input)
|
local inputnode = get_node_force(input)
|
||||||
local inputrules = mesecon.get_any_inputrules(inputnode)
|
local inputrules = mesecon.get_any_inputrules(inputnode)
|
||||||
if not inputrules then
|
if not inputrules then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
local rules = {}
|
local rules = {}
|
||||||
|
|
||||||
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
for _, inputrule in pairs(mesecon.flattenrules(inputrules)) do
|
||||||
-- Check if input accepts from output
|
-- Check if input accepts from output
|
||||||
if vector.equals(vector.add(input, inputrule), output) then
|
if equals(vector.add(input, inputrule), output) then
|
||||||
local newrule = table.copy(inputrule)
|
local newrule = copy(inputrule)
|
||||||
newrule.spread = rule.spread
|
newrule.spread = rule.spread
|
||||||
table.insert(rules, newrule)
|
insert(rules, newrule)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -545,19 +548,19 @@ end
|
||||||
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
|
-- inputnode (effector or conductor) at position `input` and has an input in direction `rule`
|
||||||
function mesecon.rules_link_rule_all_inverted(input, rule)
|
function mesecon.rules_link_rule_all_inverted(input, rule)
|
||||||
local output = vector.add(input, rule)
|
local output = vector.add(input, rule)
|
||||||
local outputnode = mesecon.get_node_force(output)
|
local outputnode = get_node_force(output)
|
||||||
local outputrules = mesecon.get_any_outputrules(outputnode)
|
local outputrules = mesecon.get_any_outputrules(outputnode)
|
||||||
if not outputrules then
|
if not outputrules then
|
||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
local rules = {}
|
local rules = {}
|
||||||
|
|
||||||
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
|
for _, outputrule in pairs(mesecon.flattenrules(outputrules)) do
|
||||||
if vector.equals(vector.add(output, outputrule), input) then
|
if equals(vector.add(output, outputrule), input) then
|
||||||
local newrule = table.copy(outputrule)
|
local newrule = copy(outputrule)
|
||||||
newrule = mesecon.invertRule(newrule)
|
newrule = invertRule(newrule)
|
||||||
newrule.spread = rule.spread
|
newrule.spread = rule.spread
|
||||||
table.insert(rules, newrule)
|
insert(rules, newrule)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return rules
|
return rules
|
||||||
|
@ -568,7 +571,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||||
if depth > 1 then
|
if depth > 1 then
|
||||||
return false, false
|
return false, false
|
||||||
end
|
end
|
||||||
local node = mesecon.get_node_force(pos)
|
local node = get_node_force(pos)
|
||||||
local rules = mesecon.get_any_inputrules(node)
|
local rules = mesecon.get_any_inputrules(node)
|
||||||
if not rules then
|
if not rules then
|
||||||
return false, false
|
return false, false
|
||||||
|
@ -584,23 +587,23 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||||
|
|
||||||
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
local function power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
||||||
local spread = false
|
local spread = false
|
||||||
for _, rname in ipairs(rulenames) do
|
for _, rname in pairs(rulenames) do
|
||||||
local np = vector.add(pos, rname)
|
local np = vector.add(pos, rname)
|
||||||
local nn = mesecon.get_node_force(np)
|
local nn = get_node_force(np)
|
||||||
if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname))
|
if (mesecon.is_conductor_on (nn, invertRule(rname))
|
||||||
or mesecon.is_receptor_on (nn.name)) then
|
or is_receptor_on (nn.name)) then
|
||||||
if not vector.equals(home_pos, np) then
|
if not equals(home_pos, np) then
|
||||||
local rulez = mesecon.get_any_outputrules(nn)
|
local rulez = mesecon.get_any_outputrules(nn)
|
||||||
local spread_tmp = false
|
local spread_tmp = false
|
||||||
for r=1, #rulez do
|
for r=1, #rulez do
|
||||||
if vector.equals(mesecon.invertRule(rname), rulez[r]) then
|
if equals(invertRule(rname), rulez[r]) then
|
||||||
if rulez[r].spread then
|
if rulez[r].spread then
|
||||||
spread_tmp = true
|
spread_tmp = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if depth == 0 or spread_tmp then
|
if depth == 0 or spread_tmp then
|
||||||
table.insert(sourcepos, np)
|
insert(sourcepos, np)
|
||||||
if spread_tmp then
|
if spread_tmp then
|
||||||
spread = true
|
spread = true
|
||||||
end
|
end
|
||||||
|
@ -618,7 +621,7 @@ function mesecon.is_powered(pos, rule, depth, sourcepos, home_pos)
|
||||||
|
|
||||||
local spread = false
|
local spread = false
|
||||||
if not rule then
|
if not rule then
|
||||||
for _, rule in ipairs(mesecon.flattenrules(rules)) do
|
for _, rule in pairs(mesecon.flattenrules(rules)) do
|
||||||
local spread_temp
|
local spread_temp
|
||||||
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
|
local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule)
|
||||||
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
sourcepos, spread_temp = power_walk(pos, home_pos, sourcepos, rulenames, rule, depth)
|
||||||
|
|
Loading…
Reference in New Issue