Page 9 of 11

PostPosted: Fri May 24, 2013 13:14
by Pavel_S
I found bag with doublechest.
Image
And fixed it
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function hacky_swap_node(pos,name,param2)
    local node = minetest.env:get_node(pos)
    local meta = minetest.env:get_meta(pos)
    if node.name == name then
        return
    end
    node.name = name
    local meta0 = meta:to_table()
   
    minetest.env:set_node(pos,{name=name,param2=param2})
                                             ^rotate added
    meta = minetest.env:get_meta(pos)
    meta:from_table(meta0)
end

PostPosted: Fri May 24, 2013 13:19
by jojoa1997
I got rid of the locked chests for shared chests. You might want to switch all items into a regular chest before I update. 2 weeks left till I can.

PostPosted: Fri May 24, 2013 13:35
by PilzAdam
Pavel_S wrote:I found bag with doublechest.
Image
And fixed it
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
local function hacky_swap_node(pos,name,param2)
    local node = minetest.env:get_node(pos)
    local meta = minetest.env:get_meta(pos)
    if node.name == name then
        return
    end
    node.name = name
    local meta0 = meta:to_table()
   
    minetest.env:set_node(pos,{name=name,param2=param2})
                                             ^rotate added
    meta = minetest.env:get_meta(pos)
    meta:from_table(meta0)
end

Ehm, I dont know where you got that version of hacky_swap_node(), but the one in MiniTest and minetest_game keep param2: https://github.com/PilzAdam/MiniTest/blob/master/mods/default/nodes.lua#L595

PostPosted: Fri May 24, 2013 13:35
by PilzAdam
jojoa1997 wrote:I got rid of the locked chests for shared chests. You might want to switch all items into a regular chest before I update. 2 weeks left till I can.

What are you talking about?

PostPosted: Fri May 24, 2013 14:00
by jojoa1997
PilzAdam wrote:
jojoa1997 wrote:I got rid of the locked chests for shared chests. You might want to switch all items into a regular chest before I update. 2 weeks left till I can.

What are you talking about?
I meant on local copy. Also minecraft doesn't have a locked chest. Is there a way I can transfer the meta data of the chest when the alias occurs?

PostPosted: Fri May 24, 2013 14:03
by Pavel_S
PilzAdam wrote:Ehm, I dont know where you got that version of hacky_swap_node(), but the one in MiniTest and minetest_game keep param2: https://github.com/PilzAdam/MiniTest/blob/master/mods/default/nodes.lua#L595

I changed hacky_swap_node().
Becouse of neighbor chest do not rotate.
See in screenshot.

PostPosted: Fri May 24, 2013 14:53
by PilzAdam
Pavel_S wrote:
PilzAdam wrote:Ehm, I dont know where you got that version of hacky_swap_node(), but the one in MiniTest and minetest_game keep param2: https://github.com/PilzAdam/MiniTest/blob/master/mods/default/nodes.lua#L595

I changed hacky_swap_node().
Becouse of neighbor chest do not rotate.
See in screenshot.

Ah, now I get it. Pushed a slightly changed fix.

PostPosted: Fri May 24, 2013 15:49
by Nore
A little suggestion, since I saw you didn't want to be able to place nodes above y=256:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
    if pos.y>256 then
        minetest.env:set_node(pos, oldnode)
        return true
    end
end)


Moreover, I made some changes to mesecons so that effector are only updated on serverstep. Would you like to use it for a redstone mod?

PostPosted: Fri May 24, 2013 16:02
by PilzAdam
Nore wrote:A little suggestion, since I saw you didn't want to be able to place nodes above y=256:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
    if pos.y>256 then
        minetest.env:set_node(pos, oldnode)
        return true
    end
end)


Moreover, I made some changes to mesecons so that effector are only updated on serverstep. Would you like to use it for a redstone mod?

Nice, added.

Id like to wait a bit with the redstone, its just such a huge thing.

PostPosted: Fri May 24, 2013 16:19
by jojoa1997
Nore wrote:A little suggestion, since I saw you didn't want to be able to place nodes above y=256:
Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack)
    if pos.y>256 then
        minetest.env:set_node(pos, oldnode)
        return true
    end
end)


Moreover, I made some changes to mesecons so that effector are only updated on serverstep. Would you like to use it for a redstone mod?
I would like to see it. Since i already made redstone it would be easier to integrate it in.

PostPosted: Fri May 24, 2013 16:24
by Nore
You need to replace internal.lua with that:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Internal.lua - The core of mesecons
--
-- For more practical developer resources see mesecons.tk
--
-- Function overview
-- mesecon:get_effector(nodename)     --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
-- mesecon:get_receptor(nodename)     --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
-- mesecon:get_conductor(nodename)    --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
-- mesecon:get_any_inputrules (node)  --> Returns the rules of a node if it is a conductor or an effector
-- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor

-- RECEPTORS
-- mesecon:is_receptor(nodename)     --> Returns true if nodename is a receptor
-- mesecon:is_receptor_on(nodename)  --> Returns true if nodename is an receptor with state = mesecon.state.on
-- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
-- mesecon:receptor_get_rules(node)  --> Returns the rules of the receptor (mesecon.rules.default if none specified)

-- EFFECTORS
-- mesecon:is_effector(nodename)     --> Returns true if nodename is an effector
-- mesecon:is_effector_on(nodename)  --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
-- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
-- mesecon:effector_get_rules(node)  --> Returns the input rules of the effector (mesecon.rules.default if none specified)

-- SIGNALS
-- mesecon:activate(pos, node)     --> Activates   the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
-- mesecon:deactivate(pos, node)   --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off)
-- mesecon:changesignal(pos, node, rulename, newstate) --> Changes     the effector node at the specific pos (calls nodedef.mesecons.effector.action_change)

-- RULES
-- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name
-- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name

-- CONDUCTORS
-- mesecon:is_conductor(nodename)     --> Returns true if nodename is a conductor
-- mesecon:is_conductor_on(nodename)  --> Returns true if nodename is a conductor with state = mesecon.state.on
-- mesecon:is_conductor_off(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.off
-- mesecon:get_conductor_on(offstate) --> Returns the onstate  nodename of the conductor with the name offstate
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate
-- mesecon:conductor_get_rules(node)  --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)

-- 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:turnon(pos, rulename)        --> Returns true  whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon
-- mesecon:turnoff(pos, rulename)       --> Turns off whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnoff
-- mesecon:connected_to_receptor(pos)   --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive
-- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
-- mesecon:rules_link_anydir(outp., inp., d_outpr.)   --> Same as rules mesecon:rules_link but also returns true if output and input are swapped
-- mesecon:is_powered(pos)              --> Returns true if pos is powered by a receptor or a conductor

-- RULES ROTATION helpsers
-- mesecon:rotate_rules_right(rules)
-- mesecon:rotate_rules_left(rules)
-- mesecon:rotate_rules_up(rules)
-- mesecon:rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction

-- General
function mesecon:get_effector(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.effector then
        return minetest.registered_nodes[nodename].mesecons.effector
    end
end

function mesecon:get_receptor(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.receptor then
        return minetest.registered_nodes[nodename].mesecons.receptor
    end
end

function mesecon:get_conductor(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.conductor then
        return minetest.registered_nodes[nodename].mesecons.conductor
    end
end

function mesecon:get_any_outputrules (node)
    if mesecon:is_conductor(node.name) then
        return mesecon:conductor_get_rules(node)
    elseif mesecon:is_receptor(node.name) then
        return mesecon:receptor_get_rules(node)
    end
    return false
end

function mesecon:get_any_inputrules (node)
    if mesecon:is_conductor(node.name) then
        return mesecon:conductor_get_rules(node)
    elseif mesecon:is_effector(node.name) then
        return mesecon:effector_get_rules(node)
    end
    return false
end

-- Receptors
-- Nodes that can power mesecons
function mesecon:is_receptor_on(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor and receptor.state == mesecon.state.on then
        return true
    end
    return false
end

function mesecon:is_receptor_off(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor and receptor.state == mesecon.state.off then
        return true
    end
    return false
end

function mesecon:is_receptor(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor then
        return true
    end
    return false
end

function mesecon:receptor_get_rules(node)
    local receptor = mesecon:get_receptor(node.name)
    if receptor then
        local rules = receptor.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end

    return mesecon.rules.default
end

-- Effectors
-- Nodes that can be powered by mesecons
function mesecon:is_effector_on(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector and effector.action_off then
        return true
    end
    return false
end

function mesecon:is_effector_off(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector and effector.action_on then
        return true
    end
    return false
end

function mesecon:is_effector(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector then
        return true
    end
    return false
end

function mesecon:effector_get_rules(node)
    local effector = mesecon:get_effector(node.name)
    if effector then
        local rules = effector.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end
    return mesecon.rules.default
end

--Signals

function mesecon:activate(pos, node, rulename)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_on then
    --    effector.action_on (pos, node, rulename)
    --end
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:activate(pos, node, rule)
        end
        return
    end
    add_action(pos, "on", rulename)
end

function mesecon:deactivate(pos, node, rulename)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_off then
    --    effector.action_off (pos, node, rulename)
    --end
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:deactivate(pos, node, rule)
        end
        return
    end
    add_action(pos, "off", rulename)
end

function mesecon:changesignal(pos, node, rulename, newstate)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_change then
    --    effector.action_change (pos, node, rulename, newstate)
    --end
    newstate = newstate or "on"
    --rulename = rulename or mesecon.rules.default
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:changesignal(pos, node, rule, newstate)
        end
        return
    end
    add_action(pos, "c"..newstate, rulename)
end

function execute_actions(dtime)
    local nactions = mesecon.to_update
    mesecon.to_update = {}
    for _,i in ipairs(nactions) do
        node = minetest.env:get_node(i.pos)
        effector = mesecon:get_effector(node.name)
        if i.action == "on" then
            if effector and effector.action_on then
                effector.action_on(i.pos, node, i.rname)
            end
        elseif i.action == "off" then
            if effector and effector.action_off then
                effector.action_off(i.pos, node, i.rname)
            end
        elseif i.action == "con" then
            if effector and effector.action_change then
                effector.action_change(i.pos, node, i.rname, "on")
            end
        elseif i.action == "coff" then
            if effector and effector.action_change then
                effector.action_change(i.pos, node, i.rname, "off")
            end
        end
    end
    local nactions = mesecon.r_to_update
    mesecon.r_to_update = {}
    for _,i in ipairs(nactions) do
        if i.action == "on" then
            mesecon:receptor_on_i(i.pos, i.rules)
        else
            mesecon:receptor_off_i(i.pos,i.rules)
        end
    end
end

minetest.register_globalstep(execute_actions)

function add_action(pos, action, rname)
    for _,i in ipairs(mesecon.to_update) do
        if i.pos.x == pos.x and i.pos.y == pos.y and i.pos.z == pos.z and i.rname.x == rname.x and i.rname.y == rname.y and i.rname.z == rname.z then
            if (i.action == "on" and action == "on") or (i.action == "off" and action == "off") then
                --nothing
            elseif i.action == "coff" and action == "on" then i.action = "on"
            elseif i.action == "con" and action == "off" then i.action = "off"
            else
                if action == "on" or action == "con" then i.action = "con" end
                if action == "off" or action == "coff" then i.action = "coff" end
            end
            break
        end
    end
    mesecon.to_update[#mesecon.to_update+1] = {pos = pos, action = action, rname = rname}
end

--Rules

function mesecon:add_rules(name, rules)
    mesecon.rules[name] = rules
end

function mesecon:get_rules(name)
    return mesecon.rules[name]
end

-- Conductors

function mesecon:is_conductor_on(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor and conductor.state == mesecon.state.on then
        return true
    end
    return false
end

function mesecon:is_conductor_off(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor and conductor.state == mesecon.state.off then
        return true
    end
    return false
end

function mesecon:is_conductor(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor then
        return true
    end
    return false
end

function mesecon:get_conductor_on(offstate)
    local conductor = mesecon:get_conductor(offstate)
    if conductor then
        return conductor.onstate
    end
    return false
end

function mesecon:get_conductor_off(onstate)
    local conductor = mesecon:get_conductor(onstate)
    if conductor then
        return conductor.offstate
    end
    return false
end

function mesecon:conductor_get_rules(node)
    local conductor = mesecon:get_conductor(node.name)
    if conductor then
        local rules = conductor.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end
    return mesecon.rules.default
end

-- some more general high-level stuff

function mesecon:is_power_on(pos)
    local node = minetest.env:get_node(pos)
    if mesecon:is_conductor_on(node.name) or mesecon:is_receptor_on(node.name) then
        return true
    end
    return false
end

function mesecon:is_power_off(pos)
    local node = minetest.env:get_node(pos)
    if mesecon:is_conductor_off(node.name) or mesecon:is_receptor_off(node.name) then
        return true
    end
    return false
end

function mesecon:turnon(pos, rulename)
    local node = minetest.env:get_node(pos)

    if mesecon:is_conductor_off(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        minetest.env:add_node(pos, {name = mesecon:get_conductor_on(node.name), param2 = node.param2})

        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            local link, rulename = mesecon:rules_link(pos, np)

            if link then
                mesecon:turnon(np, rulename)
            end
        end
    elseif mesecon:is_effector(node.name) then
        mesecon:changesignal(pos, node, rulename, mesecon.state.on)
        if mesecon:is_effector_off(node.name) then
            mesecon:activate(pos, node, rulename)
        end
    end
end

function mesecon:turnoff(pos, rulename)
    local node = minetest.env:get_node(pos)

    if mesecon:is_conductor_on(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        minetest.env:add_node(pos, {name = mesecon:get_conductor_off(node.name), param2 = node.param2})

        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            local link, rulename = mesecon:rules_link(pos, np)

            if link then
                mesecon:turnoff(np, rulename)
            end
        end
    elseif mesecon:is_effector(node.name) then
        mesecon:changesignal(pos, node, rulename, mesecon.state.off)
        if mesecon:is_effector_on(node.name)
        and not mesecon:is_powered(pos) then
            mesecon:deactivate(pos, node, rulename)
        end
    end
end


function mesecon:connected_to_receptor(pos)
    local node = minetest.env:get_node(pos)

    -- Check if conductors around are connected
    local rules = mesecon:get_any_inputrules(node)
    if not rules then return false end

    for _, rule in ipairs(rules) do
        local np = mesecon:addPosRule(pos, rule)
        if mesecon:rules_link(np, pos) then
            if mesecon:find_receptor_on(np, {}) then
                return true
            end
        end
    end

    return false
end

function mesecon:find_receptor_on(pos, checked)
    -- find out if node has already been checked (to prevent from endless loop)
    for _, cp in ipairs(checked) do
        if mesecon:cmpPos(cp, pos) then
            return false, checked
        end
    end

    -- add current position to checked
    table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
    local node = minetest.env:get_node(pos)

    if mesecon:is_receptor_on(node.name) then
        return true
    end

    if mesecon:is_conductor(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            if mesecon:rules_link(np, pos) then
                if mesecon:find_receptor_on(np, checked) then
                    return true
                end
            end
        end
    end

    return false
end

function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
    local outputnode = minetest.env:get_node(output)
    local inputnode = minetest.env:get_node(input)
    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

    for _, outputrule in ipairs(outputrules) do
        -- Check if output sends to input
        if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
            for _, inputrule in ipairs(inputrules) do
                -- Check if input accepts from output
                if  mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
                    return true, inputrule.name
                end
            end
        end
    end
    return false
end

function mesecon:rules_link_anydir(pos1, pos2)
    return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
end

function mesecon:is_powered(pos)
    local node = minetest.env:get_node(pos)
    local rules = mesecon:get_any_inputrules(node)
    if not rules then return false end

    for _, rule in ipairs(rules) do
        local np = mesecon:addPosRule(pos, rule)
        local nn = minetest.env:get_node(np)

        if (mesecon:is_conductor_on (nn.name) or mesecon:is_receptor_on (nn.name))
        and mesecon:rules_link(np, pos) then
            return true
        end
    end
   
    return false
end

--Rules rotation Functions:
function mesecon:rotate_rules_right(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x = -rule.z,
            y =  rule.y,
            z =  rule.x})
    end
    return nr
end

function mesecon:rotate_rules_left(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x =  rule.z,
            y =  rule.y,
            z = -rule.x})
    end
    return nr
end

function mesecon:rotate_rules_down(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x = -rule.y,
            y =  rule.x,
            z =  rule.z})
    end
    return nr
end

function mesecon:rotate_rules_up(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x =  rule.y,
            y = -rule.x,
            z =  rule.z})
    end
    return nr
end


Moreover, do not use an abm in torches but make them instant (but everything instant will be on serverstep)

PostPosted: Fri May 24, 2013 16:26
by jojoa1997
Nore wrote:You need to replace internal.lua with that:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
-- Internal.lua - The core of mesecons
--
-- For more practical developer resources see mesecons.tk
--
-- Function overview
-- mesecon:get_effector(nodename)     --> Returns the mesecons.effector -specifictation in the nodedef by the nodename
-- mesecon:get_receptor(nodename)     --> Returns the mesecons.receptor -specifictation in the nodedef by the nodename
-- mesecon:get_conductor(nodename)    --> Returns the mesecons.conductor-specifictation in the nodedef by the nodename
-- mesecon:get_any_inputrules (node)  --> Returns the rules of a node if it is a conductor or an effector
-- mesecon:get_any_outputrules (node) --> Returns the rules of a node if it is a conductor or a receptor

-- RECEPTORS
-- mesecon:is_receptor(nodename)     --> Returns true if nodename is a receptor
-- mesecon:is_receptor_on(nodename)  --> Returns true if nodename is an receptor with state = mesecon.state.on
-- mesecon:is_receptor_off(nodename) --> Returns true if nodename is an receptor with state = mesecon.state.off
-- mesecon:receptor_get_rules(node)  --> Returns the rules of the receptor (mesecon.rules.default if none specified)

-- EFFECTORS
-- mesecon:is_effector(nodename)     --> Returns true if nodename is an effector
-- mesecon:is_effector_on(nodename)  --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_off
-- mesecon:is_effector_off(nodename) --> Returns true if nodename is an effector with nodedef.mesecons.effector.action_on
-- mesecon:effector_get_rules(node)  --> Returns the input rules of the effector (mesecon.rules.default if none specified)

-- SIGNALS
-- mesecon:activate(pos, node)     --> Activates   the effector node at the specific pos (calls nodedef.mesecons.effector.action_on)
-- mesecon:deactivate(pos, node)   --> Deactivates the effector node at the specific pos (calls nodedef.mesecons.effector.action_off)
-- mesecon:changesignal(pos, node, rulename, newstate) --> Changes     the effector node at the specific pos (calls nodedef.mesecons.effector.action_change)

-- RULES
-- mesecon:add_rules(name, rules) | deprecated? --> Saves rules table by name
-- mesecon:get_rules(name, rules) | deprecated? --> Loads rules table with name

-- CONDUCTORS
-- mesecon:is_conductor(nodename)     --> Returns true if nodename is a conductor
-- mesecon:is_conductor_on(nodename)  --> Returns true if nodename is a conductor with state = mesecon.state.on
-- mesecon:is_conductor_off(nodename) --> Returns true if nodename is a conductor with state = mesecon.state.off
-- mesecon:get_conductor_on(offstate) --> Returns the onstate  nodename of the conductor with the name offstate
-- mesecon:get_conductor_off(onstate) --> Returns the offstate nodename of the conductor with the name onstate
-- mesecon:conductor_get_rules(node)  --> Returns the input+output rules of a conductor (mesecon.rules.default if none specified)

-- 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:turnon(pos, rulename)        --> Returns true  whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnon
-- mesecon:turnoff(pos, rulename)       --> Turns off whatever there is at pos. Calls itself for connected nodes (if pos is a conductor) --> recursive, the rulename is the name of the input rule that caused calling turnoff
-- mesecon:connected_to_receptor(pos)   --> Returns true if pos is connected to a receptor directly or via conductors; calls itself if pos is a conductor --> recursive
-- mesecon:rules_link(output, input, dug_outputrules) --> Returns true if outputposition + outputrules = inputposition and inputposition + inputrules = outputposition (if the two positions connect)
-- mesecon:rules_link_anydir(outp., inp., d_outpr.)   --> Same as rules mesecon:rules_link but also returns true if output and input are swapped
-- mesecon:is_powered(pos)              --> Returns true if pos is powered by a receptor or a conductor

-- RULES ROTATION helpsers
-- mesecon:rotate_rules_right(rules)
-- mesecon:rotate_rules_left(rules)
-- mesecon:rotate_rules_up(rules)
-- mesecon:rotate_rules_down(rules)
-- These functions return rules that have been rotated in the specific direction

-- General
function mesecon:get_effector(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.effector then
        return minetest.registered_nodes[nodename].mesecons.effector
    end
end

function mesecon:get_receptor(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.receptor then
        return minetest.registered_nodes[nodename].mesecons.receptor
    end
end

function mesecon:get_conductor(nodename)
    if  minetest.registered_nodes[nodename]
    and minetest.registered_nodes[nodename].mesecons
    and minetest.registered_nodes[nodename].mesecons.conductor then
        return minetest.registered_nodes[nodename].mesecons.conductor
    end
end

function mesecon:get_any_outputrules (node)
    if mesecon:is_conductor(node.name) then
        return mesecon:conductor_get_rules(node)
    elseif mesecon:is_receptor(node.name) then
        return mesecon:receptor_get_rules(node)
    end
    return false
end

function mesecon:get_any_inputrules (node)
    if mesecon:is_conductor(node.name) then
        return mesecon:conductor_get_rules(node)
    elseif mesecon:is_effector(node.name) then
        return mesecon:effector_get_rules(node)
    end
    return false
end

-- Receptors
-- Nodes that can power mesecons
function mesecon:is_receptor_on(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor and receptor.state == mesecon.state.on then
        return true
    end
    return false
end

function mesecon:is_receptor_off(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor and receptor.state == mesecon.state.off then
        return true
    end
    return false
end

function mesecon:is_receptor(nodename)
    local receptor = mesecon:get_receptor(nodename)
    if receptor then
        return true
    end
    return false
end

function mesecon:receptor_get_rules(node)
    local receptor = mesecon:get_receptor(node.name)
    if receptor then
        local rules = receptor.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end

    return mesecon.rules.default
end

-- Effectors
-- Nodes that can be powered by mesecons
function mesecon:is_effector_on(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector and effector.action_off then
        return true
    end
    return false
end

function mesecon:is_effector_off(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector and effector.action_on then
        return true
    end
    return false
end

function mesecon:is_effector(nodename)
    local effector = mesecon:get_effector(nodename)
    if effector then
        return true
    end
    return false
end

function mesecon:effector_get_rules(node)
    local effector = mesecon:get_effector(node.name)
    if effector then
        local rules = effector.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end
    return mesecon.rules.default
end

--Signals

function mesecon:activate(pos, node, rulename)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_on then
    --    effector.action_on (pos, node, rulename)
    --end
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:activate(pos, node, rule)
        end
        return
    end
    add_action(pos, "on", rulename)
end

function mesecon:deactivate(pos, node, rulename)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_off then
    --    effector.action_off (pos, node, rulename)
    --end
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:deactivate(pos, node, rule)
        end
        return
    end
    add_action(pos, "off", rulename)
end

function mesecon:changesignal(pos, node, rulename, newstate)
    --local effector = mesecon:get_effector(node.name)
    --if effector and effector.action_change then
    --    effector.action_change (pos, node, rulename, newstate)
    --end
    newstate = newstate or "on"
    --rulename = rulename or mesecon.rules.default
    if rulename == nil then
        for _,rule in ipairs(mesecon:effector_get_rules(node)) do
            mesecon:changesignal(pos, node, rule, newstate)
        end
        return
    end
    add_action(pos, "c"..newstate, rulename)
end

function execute_actions(dtime)
    local nactions = mesecon.to_update
    mesecon.to_update = {}
    for _,i in ipairs(nactions) do
        node = minetest.env:get_node(i.pos)
        effector = mesecon:get_effector(node.name)
        if i.action == "on" then
            if effector and effector.action_on then
                effector.action_on(i.pos, node, i.rname)
            end
        elseif i.action == "off" then
            if effector and effector.action_off then
                effector.action_off(i.pos, node, i.rname)
            end
        elseif i.action == "con" then
            if effector and effector.action_change then
                effector.action_change(i.pos, node, i.rname, "on")
            end
        elseif i.action == "coff" then
            if effector and effector.action_change then
                effector.action_change(i.pos, node, i.rname, "off")
            end
        end
    end
    local nactions = mesecon.r_to_update
    mesecon.r_to_update = {}
    for _,i in ipairs(nactions) do
        if i.action == "on" then
            mesecon:receptor_on_i(i.pos, i.rules)
        else
            mesecon:receptor_off_i(i.pos,i.rules)
        end
    end
end

minetest.register_globalstep(execute_actions)

function add_action(pos, action, rname)
    for _,i in ipairs(mesecon.to_update) do
        if i.pos.x == pos.x and i.pos.y == pos.y and i.pos.z == pos.z and i.rname.x == rname.x and i.rname.y == rname.y and i.rname.z == rname.z then
            if (i.action == "on" and action == "on") or (i.action == "off" and action == "off") then
                --nothing
            elseif i.action == "coff" and action == "on" then i.action = "on"
            elseif i.action == "con" and action == "off" then i.action = "off"
            else
                if action == "on" or action == "con" then i.action = "con" end
                if action == "off" or action == "coff" then i.action = "coff" end
            end
            break
        end
    end
    mesecon.to_update[#mesecon.to_update+1] = {pos = pos, action = action, rname = rname}
end

--Rules

function mesecon:add_rules(name, rules)
    mesecon.rules[name] = rules
end

function mesecon:get_rules(name)
    return mesecon.rules[name]
end

-- Conductors

function mesecon:is_conductor_on(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor and conductor.state == mesecon.state.on then
        return true
    end
    return false
end

function mesecon:is_conductor_off(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor and conductor.state == mesecon.state.off then
        return true
    end
    return false
end

function mesecon:is_conductor(nodename)
    local conductor = mesecon:get_conductor(nodename)
    if conductor then
        return true
    end
    return false
end

function mesecon:get_conductor_on(offstate)
    local conductor = mesecon:get_conductor(offstate)
    if conductor then
        return conductor.onstate
    end
    return false
end

function mesecon:get_conductor_off(onstate)
    local conductor = mesecon:get_conductor(onstate)
    if conductor then
        return conductor.offstate
    end
    return false
end

function mesecon:conductor_get_rules(node)
    local conductor = mesecon:get_conductor(node.name)
    if conductor then
        local rules = conductor.rules
        if type(rules) == 'function' then
            return rules(node)
        elseif rules then
            return rules
        end
    end
    return mesecon.rules.default
end

-- some more general high-level stuff

function mesecon:is_power_on(pos)
    local node = minetest.env:get_node(pos)
    if mesecon:is_conductor_on(node.name) or mesecon:is_receptor_on(node.name) then
        return true
    end
    return false
end

function mesecon:is_power_off(pos)
    local node = minetest.env:get_node(pos)
    if mesecon:is_conductor_off(node.name) or mesecon:is_receptor_off(node.name) then
        return true
    end
    return false
end

function mesecon:turnon(pos, rulename)
    local node = minetest.env:get_node(pos)

    if mesecon:is_conductor_off(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        minetest.env:add_node(pos, {name = mesecon:get_conductor_on(node.name), param2 = node.param2})

        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            local link, rulename = mesecon:rules_link(pos, np)

            if link then
                mesecon:turnon(np, rulename)
            end
        end
    elseif mesecon:is_effector(node.name) then
        mesecon:changesignal(pos, node, rulename, mesecon.state.on)
        if mesecon:is_effector_off(node.name) then
            mesecon:activate(pos, node, rulename)
        end
    end
end

function mesecon:turnoff(pos, rulename)
    local node = minetest.env:get_node(pos)

    if mesecon:is_conductor_on(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        minetest.env:add_node(pos, {name = mesecon:get_conductor_off(node.name), param2 = node.param2})

        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            local link, rulename = mesecon:rules_link(pos, np)

            if link then
                mesecon:turnoff(np, rulename)
            end
        end
    elseif mesecon:is_effector(node.name) then
        mesecon:changesignal(pos, node, rulename, mesecon.state.off)
        if mesecon:is_effector_on(node.name)
        and not mesecon:is_powered(pos) then
            mesecon:deactivate(pos, node, rulename)
        end
    end
end


function mesecon:connected_to_receptor(pos)
    local node = minetest.env:get_node(pos)

    -- Check if conductors around are connected
    local rules = mesecon:get_any_inputrules(node)
    if not rules then return false end

    for _, rule in ipairs(rules) do
        local np = mesecon:addPosRule(pos, rule)
        if mesecon:rules_link(np, pos) then
            if mesecon:find_receptor_on(np, {}) then
                return true
            end
        end
    end

    return false
end

function mesecon:find_receptor_on(pos, checked)
    -- find out if node has already been checked (to prevent from endless loop)
    for _, cp in ipairs(checked) do
        if mesecon:cmpPos(cp, pos) then
            return false, checked
        end
    end

    -- add current position to checked
    table.insert(checked, {x=pos.x, y=pos.y, z=pos.z})
    local node = minetest.env:get_node(pos)

    if mesecon:is_receptor_on(node.name) then
        return true
    end

    if mesecon:is_conductor(node.name) then
        local rules = mesecon:conductor_get_rules(node)
        for _, rule in ipairs(rules) do
            local np = mesecon:addPosRule(pos, rule)
            if mesecon:rules_link(np, pos) then
                if mesecon:find_receptor_on(np, checked) then
                    return true
                end
            end
        end
    end

    return false
end

function mesecon:rules_link(output, input, dug_outputrules) --output/input are positions (outputrules optional, used if node has been dug), second return value: the name of the affected input rule
    local outputnode = minetest.env:get_node(output)
    local inputnode = minetest.env:get_node(input)
    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

    for _, outputrule in ipairs(outputrules) do
        -- Check if output sends to input
        if mesecon:cmpPos(mesecon:addPosRule(output, outputrule), input) then
            for _, inputrule in ipairs(inputrules) do
                -- Check if input accepts from output
                if  mesecon:cmpPos(mesecon:addPosRule(input, inputrule), output) then
                    return true, inputrule.name
                end
            end
        end
    end
    return false
end

function mesecon:rules_link_anydir(pos1, pos2)
    return mesecon:rules_link(pos1, pos2) or mesecon:rules_link(pos2, pos1)
end

function mesecon:is_powered(pos)
    local node = minetest.env:get_node(pos)
    local rules = mesecon:get_any_inputrules(node)
    if not rules then return false end

    for _, rule in ipairs(rules) do
        local np = mesecon:addPosRule(pos, rule)
        local nn = minetest.env:get_node(np)

        if (mesecon:is_conductor_on (nn.name) or mesecon:is_receptor_on (nn.name))
        and mesecon:rules_link(np, pos) then
            return true
        end
    end
   
    return false
end

--Rules rotation Functions:
function mesecon:rotate_rules_right(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x = -rule.z,
            y =  rule.y,
            z =  rule.x})
    end
    return nr
end

function mesecon:rotate_rules_left(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x =  rule.z,
            y =  rule.y,
            z = -rule.x})
    end
    return nr
end

function mesecon:rotate_rules_down(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x = -rule.y,
            y =  rule.x,
            z =  rule.z})
    end
    return nr
end

function mesecon:rotate_rules_up(rules)
    local nr = {}
    for i, rule in ipairs(rules) do
        table.insert(nr, {
            x =  rule.y,
            y = -rule.x,
            z =  rule.z})
    end
    return nr
end


Moreover, do not use an abm in torches but make them instant (but everything instant will be on serverstep)
ok what do you mean by instant and not an abm and also will this affect anything in the other files to were i cant change a certain thing in them?

PostPosted: Fri May 24, 2013 16:37
by Nore
That means, make torches like that:

Your phone or window isn't wide enough to display the code box. If it's a phone, try rotating it to landscape mode.
Code: Select all
--MESECON TORCHES

local rotate_torch_rules = function (rules, param2)
    if param2 == 5 then
        return mesecon:rotate_rules_right(rules)
    elseif param2 == 2 then
        return mesecon:rotate_rules_right(mesecon:rotate_rules_right(rules)) --180 degrees
    elseif param2 == 4 then
        return mesecon:rotate_rules_left(rules)
    elseif param2 == 1 then
        return mesecon:rotate_rules_down(rules)
    elseif param2 == 0 then
        return mesecon:rotate_rules_up(rules)
    else
        return rules
    end
end

local torch_get_output_rules = function(node)
    local rules = {
        {x = 1,  y = 0, z = 0},
        {x = 0,  y = 0, z = 1},
        {x = 0,  y = 0, z =-1},
        {x = 0,  y = 1, z = 0},
        {x = 0,  y =-1, z = 0}}

    return rotate_torch_rules(rules, node.param2)
end

local torch_get_input_rules = function(node)
    local rules =     {{x = -2, y = 0, z = 0},
                 {x = -1, y = 1, z = 0}}

    return rotate_torch_rules(rules, node.param2)
end

minetest.register_craft({
    output = '"mesecons_torch:mesecon_torch_on" 4',
    recipe = {
    {"group:mesecon_conductor_craftable"},
    {"default:stick"},}
})

local torch_selectionbox =
{
    type = "wallmounted",
    wall_top = {-0.1, 0.5-0.6, -0.1, 0.1, 0.5, 0.1},
    wall_bottom = {-0.1, -0.5, -0.1, 0.1, -0.5+0.6, 0.1},
    wall_side = {-0.5, -0.1, -0.1, -0.5+0.6, 0.1, 0.1},
}

minetest.register_node("mesecons_torch:mesecon_torch_off", {
    drawtype = "torchlike",
    tiles = {"jeija_torches_off.png", "jeija_torches_off_ceiling.png", "jeija_torches_off_side.png"},
    inventory_image = "jeija_torches_off.png",
    paramtype = "light",
    walkable = false,
    paramtype2 = "wallmounted",
    selection_box = torch_selectionbox,
    groups = {dig_immediate = 3, not_in_creative_inventory = 1},
    drop = "mesecons_torch:mesecon_torch_on",
    mesecons = {receptor = {
        state = mesecon.state.off,
        rules = torch_get_output_rules
    },
    effector = {
        rules = torch_get_input_rules,
        action_off = function(pos,node)
            mesecon:swap_node(pos, "mesecons_torch:mesecon_torch_on")
        end
    }}
})

minetest.register_node("mesecons_torch:mesecon_torch_on", {
    drawtype = "torchlike",
    tiles = {"jeija_torches_on.png", "jeija_torches_on_ceiling.png", "jeija_torches_on_side.png"},
    inventory_image = "jeija_torches_on.png",
    wield_image = "jeija_torches_on.png",
    paramtype = "light",
    sunlight_propagates = true,
    walkable = false,
    paramtype2 = "wallmounted",
    selection_box = torch_selectionbox,
    groups = {dig_immediate=3},
    light_source = LIGHT_MAX-5,
    description="Mesecon Torch",
    mesecons = {receptor = {
        state = mesecon.state.on,
        rules = torch_get_output_rules
    },
    effector = {
        rules = torch_get_input_rules,
        action_on = function(pos,node)
            mesecon:swap_node(pos, "mesecons_torch:mesecon_torch_off")
        end
    }},
})

-- Param2 Table (Block Attached To)
-- 5 = z-1
-- 3 = x-1
-- 4 = z+1
-- 2 = x+1
-- 0 = y+1
-- 1 = y-1

PostPosted: Sat May 25, 2013 20:15
by PilzAdam
Finally found a way to improve the workbench a lot. Its now 500% better!

PostPosted: Mon May 27, 2013 10:43
by Zeg9
PilzAdam wrote:Finally found a way to improve the workbench a lot. Its now 500% better!

Great. The last issue is the inventory being laggy... (engine problem I guess)

PostPosted: Mon May 27, 2013 13:14
by PilzAdam
I changed all the digging times to be extremly simliar to Minecraft.
Please report if you cant dig a block.

PostPosted: Sat Jun 08, 2013 17:24
by eduardo_cam199
nice game but i cant found Diamonds!!, i use 0.4.7 version

the game its no compatible with mesecons,why??


in this game you cant do sticky pistons... so why redstone if it dont have utility.

thanks and (sorry for my bad english)

PostPosted: Sat Jun 08, 2013 18:14
by PilzAdam
eduardo_cam199 wrote:nice game but i cant found Diamonds!!, i use 0.4.7 version

the game its no compatible with mesecons,why??


in this game you cant do sticky pistons... so why redstone if it dont have utility.

thanks and (sorry for my bad english)

This game is not compatible with any mod.
And the redstone isnt finished yet, Im still working on this.

PostPosted: Sat Jun 08, 2013 18:19
by eduardo_cam199
its posible found gold and diamonds in this game???

PostPosted: Sat Jun 08, 2013 20:16
by PilzAdam
eduardo_cam199 wrote:its posible found gold and diamonds in this game???

Gold, diamonds and redstone are pretty rare.

PostPosted: Sat Jun 08, 2013 22:54
by eduardo_cam199
how can i get wool and cotton seeds???

PostPosted: Sat Jun 08, 2013 23:02
by eduardo_cam199
i cant get dyes from flowers....

sorry for the excesive number of questions

PostPosted: Sat Jun 08, 2013 23:14
by PilzAdam
eduardo_cam199 wrote:how can i get wool and cotton seeds???

Dig junglegrass.
eduardo_cam199 wrote:i cant get dyes from flowers....

Strange...

PostPosted: Sun Jun 09, 2013 00:51
by eduardo_cam199
PilzAdam wrote:I changed all the digging times to be extremly simliar to Minecraft.
Please report if you cant dig a block.


i cant dig the obsidian with any pickaxe....

PostPosted: Sun Jun 09, 2013 11:11
by PilzAdam
eduardo_cam199 wrote:
PilzAdam wrote:I changed all the digging times to be extremly simliar to Minecraft.
Please report if you cant dig a block.


i cant dig the obsidian with any pickaxe....

You need a diamond pick.

PostPosted: Fri Jun 14, 2013 03:23
by eduardo_cam199
PilzAdam wrote:
eduardo_cam199 wrote:
PilzAdam wrote:I changed all the digging times to be extremly simliar to Minecraft.
Please report if you cant dig a block.


i cant dig the obsidian with any pickaxe....

You need a diamond pick.


the diamond pick dont dig the obsidian blocks

PostPosted: Fri Jun 14, 2013 09:50
by Topywo
eduardo_cam199 wrote:the diamond pick dont dig the obsidian blocks


Maybe:
1. You need to keep down the left mouse button for a longer period (do you see the 'crack' in the obsidian block?)
2. Don't use (other) mods that have obsidian blocks. For example the obsidian block from the obsidian mod can't be dug with a diamond block. It has different specifications than the default-obsidian block.

PostPosted: Fri Jun 14, 2013 10:34
by PilzAdam
eduardo_cam199 wrote:
PilzAdam wrote:
eduardo_cam199 wrote:
i cant dig the obsidian with any pickaxe....

You need a diamond pick.


the diamond pick dont dig the obsidian blocks

The digging time of obsidian with a diamond pick is 9 seconds, you need to hold down the left mouse button all the time.

PostPosted: Fri Jun 14, 2013 13:09
by jojoa1997
Would it be OK with you PilzAdam is I just made a pull request with all the Redstone stuff I made?

PostPosted: Fri Jun 14, 2013 13:12
by PilzAdam
jojoa1997 wrote:Would it be OK with you PilzAdam is I just made a pull request with all the Redstone stuff I made?

Ehm, it already has redstone. And I have written it completly from scratch, so your version is most likely not compatible.