From 1522c875ae24fca99eadfce1e3813c323d93ceac Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Jan 2018 02:44:00 +0100 Subject: [PATCH] Code opaque block redstone power rule (part 1) --- mods/ITEMS/REDSTONE/mesecons/internal.lua | 51 ++++++++++++++--------- mods/ITEMS/REDSTONE/mesecons/services.lua | 33 ++++++++++++++- mods/ITEMS/REDSTONE/mesecons/util.lua | 9 +--- 3 files changed, 64 insertions(+), 29 deletions(-) diff --git a/mods/ITEMS/REDSTONE/mesecons/internal.lua b/mods/ITEMS/REDSTONE/mesecons/internal.lua index ffde3b664..89c8426b7 100644 --- a/mods/ITEMS/REDSTONE/mesecons/internal.lua +++ b/mods/ITEMS/REDSTONE/mesecons/internal.lua @@ -37,7 +37,7 @@ -- HIGH-LEVEL Internals -- mesecon.is_power_on(pos) --> Returns true if pos emits power in any way -- mesecon.is_power_off(pos) --> Returns true if pos does not emit power in any way --- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor or a conductor +-- mesecon.is_powered(pos) --> Returns true if pos is powered by a receptor, a conductor or an opaque block -- RULES ROTATION helpers -- mesecon.rotate_rules_right(rules) @@ -78,6 +78,8 @@ function mesecon.get_any_outputrules(node) return mesecon.conductor_get_rules(node) elseif mesecon.is_receptor(node.name) then return mesecon.receptor_get_rules(node) + elseif minetest.get_item_group(node.name, "opaque") == 1 then + return mesecon.rules.alldirs end end @@ -88,6 +90,8 @@ function mesecon.get_any_inputrules(node) return mesecon.conductor_get_rules(node) elseif mesecon.is_effector(node.name) then return mesecon.effector_get_rules(node) + elseif minetest.get_item_group(node.name, "opaque") == 1 then + return mesecon.rules.alldirs end end @@ -512,37 +516,45 @@ function mesecon.rules_link_rule_all_inverted(input, rule) return rules end -function mesecon.is_powered(pos, rule) +function mesecon.is_powered(pos, rule, depth, sourcepos) + if depth == nil then depth = 0 end + if depth > 1 then + return false + end local node = mesecon.get_node_force(pos) local rules = mesecon.get_any_inputrules(node) - if not rules then return false end + if not rules then + return false + end -- List of nodes that send out power to pos - local sourcepos = {} + if sourcepos == nil then + sourcepos = {} + end - if not rule then - for _, rule in ipairs(mesecon.flattenrules(rules)) do - local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) - for _, rname in ipairs(rulenames) do - local np = vector.add(pos, rname) - local nn = mesecon.get_node_force(np) - - if (mesecon.is_conductor_on(nn, mesecon.invertRule(rname)) - or mesecon.is_receptor_on(nn.name)) then - table.insert(sourcepos, np) - end - end - end - else - local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) + local function power_walk(pos, sourcepos, rulenames, rule, depth) for _, rname in ipairs(rulenames) do local np = vector.add(pos, rname) local nn = mesecon.get_node_force(np) if (mesecon.is_conductor_on (nn, mesecon.invertRule(rname)) or mesecon.is_receptor_on (nn.name)) then table.insert(sourcepos, np) + elseif depth == 0 and minetest.get_item_group(nn.name, "opaque") == 1 then + local more_sourcepos = mesecon.is_powered(np, nil, depth + 1, sourcepos) + mesecon.mergetable(sourcepos, more_sourcepos) end end + return sourcepos + end + + if not rule then + for _, rule in ipairs(mesecon.flattenrules(rules)) do + local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) + sourcepos = power_walk(pos, sourcepos, rulenames, rule, depth) + end + else + local rulenames = mesecon.rules_link_rule_all_inverted(pos, rule) + sourcepos = power_walk(pos, sourcepos, rulenames, rule, depth) end -- Return FALSE if not powered, return list of sources if is powered @@ -550,4 +562,3 @@ function mesecon.is_powered(pos, rule) else return sourcepos end end - diff --git a/mods/ITEMS/REDSTONE/mesecons/services.lua b/mods/ITEMS/REDSTONE/mesecons/services.lua index 1e12de08e..087ec82d9 100644 --- a/mods/ITEMS/REDSTONE/mesecons/services.lua +++ b/mods/ITEMS/REDSTONE/mesecons/services.lua @@ -50,6 +50,23 @@ mesecon.on_placenode = function(pos, node) end end end + + if minetest.get_item_group(node.name, "opaque") == 1 then + local neighbors = mesecon.mcl_get_neighbors(pos) + local is_powered = mesecon.is_powered(pos) + if is_powered then + for n=1, #neighbors do + local npos = neighbors[n].pos + local nnode = minetest.get_node(npos) + if mesecon.is_conductor_off(nnode) then + mesecon.receptor_on(npos, mesecon.conductor_get_rules(nnode)) + elseif mesecon.is_effector_off(nnode.name) then + mesecon.changesignal(npos, nnode, neighbors[n].link, mesecon.state.on, 1) + mesecon.activate(npos, nnode, neighbors[n].link, 1) + end + end + end + end end mesecon.on_dignode = function(pos, node) @@ -58,7 +75,21 @@ mesecon.on_dignode = function(pos, node) elseif mesecon.is_receptor_on(node.name) then mesecon.receptor_off(pos, mesecon.receptor_get_rules(node)) end - + if minetest.get_item_group(node.name, "opaque") == 1 then + local sources = mesecon.is_powered(pos) + local neighbors = mesecon.mcl_get_neighbors(pos) + for n=1, #neighbors do + local npos = neighbors[n].pos + local nlink = neighbors[n].link + local nnode = minetest.get_node(npos) + if mesecon.is_conductor_on(nnode) and not mesecon.is_powered(npos) then + mesecon.receptor_off(npos, mesecon.conductor_get_rules(nnode)) + elseif mesecon.is_effector_on(nnode.name) and not mesecon.is_powered(npos) then + mesecon.changesignal(npos, nnode, nlink, mesecon.state.off, 1) + mesecon.deactivate(npos, nnode, nlink, 1) + end + end + end mesecon.execute_autoconnect_hooks_queue(pos, node) end diff --git a/mods/ITEMS/REDSTONE/mesecons/util.lua b/mods/ITEMS/REDSTONE/mesecons/util.lua index f6dac3f5f..c848b9d3e 100644 --- a/mods/ITEMS/REDSTONE/mesecons/util.lua +++ b/mods/ITEMS/REDSTONE/mesecons/util.lua @@ -147,14 +147,7 @@ end -- (nodes which touch the sides of pos). -- NOT PART OF ORIGINAL MESECONS! function mesecon.mcl_get_neighbors(pos) - local r = { - { x= 0, y= 0, z=-1 }, - { x= 0, y= 0, z= 1 }, - { x= 0, y=-1, z= 0 }, - { x= 0, y= 1, z= 0 }, - { x=-1, y= 0, z= 0 }, - { x= 1, y= 0, z= 0 }, - } + local r = mesecon.rules.alldirs local e = {} for i=1, #r do table.insert(e, { pos = vector.add(pos, r[i]), link = r[i] })