forked from Mirrorlandia_minetest/mesecons
Rewrite Logic Gates: Makes it super-easy to add new gates and cleans up code
Fix bugs in the Luacontroller (when placing, false input pin values were given) and fix variables leaking into the global environment in pistons.
This commit is contained in:
parent
d2373eb605
commit
c326dc221a
@ -240,7 +240,10 @@ function mesecon.changesignal(pos, node, rulename, newstate, depth)
|
||||
return
|
||||
end
|
||||
|
||||
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, rulename, 1 / depth)
|
||||
-- Include "change" in overwritecheck so that it cannot be overwritten
|
||||
-- by "active" / "deactivate" that will be called upon the node at the same time.
|
||||
local overwritecheck = {"change", rulename}
|
||||
mesecon.queue:add_action(pos, "change", {rulename, newstate}, nil, overwritecheck, 1 / depth)
|
||||
end
|
||||
|
||||
-- Conductors
|
||||
@ -514,14 +517,11 @@ function mesecon.rules_link(output, input, dug_outputrules) --output/input are p
|
||||
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
||||
-- Check if input accepts from output
|
||||
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then
|
||||
if inputrule.sx == nil or outputrule.sx == nil
|
||||
or mesecon.cmpSpecial(inputrule, outputrule) then
|
||||
return true, inputrule
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
@ -537,12 +537,9 @@ function mesecon.rules_link_rule_all(output, rule)
|
||||
for _, inputrule in ipairs(mesecon.flattenrules(inputrules)) do
|
||||
-- Check if input accepts from output
|
||||
if mesecon.cmpPos(mesecon.addPosRule(input, inputrule), output) then
|
||||
if inputrule.sx == nil or rule.sx == nil
|
||||
or mesecon.cmpSpecial(inputrule, rule) then
|
||||
table.insert(rules, inputrule)
|
||||
end
|
||||
end
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
@ -558,12 +555,9 @@ function mesecon.rules_link_rule_all_inverted(input, rule)
|
||||
|
||||
for _, outputrule in ipairs(mesecon.flattenrules(outputrules)) do
|
||||
if mesecon.cmpPos(mesecon.addPosRule(output, outputrule), input) then
|
||||
if outputrule.sx == nil or rule.sx == nil
|
||||
or mesecon.cmpSpecial(outputrule, rule) then
|
||||
table.insert(rules, mesecon.invertRule(outputrule))
|
||||
end
|
||||
end
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
@ -612,20 +606,11 @@ end
|
||||
function mesecon.rotate_rules_right(rules)
|
||||
local nr = {}
|
||||
for i, rule in ipairs(rules) do
|
||||
if rule.sx then
|
||||
table.insert(nr, {
|
||||
x = -rule.z,
|
||||
y = rule.y,
|
||||
z = rule.x,
|
||||
sx = -rule.sz,
|
||||
sy = rule.sy,
|
||||
sz = rule.sx})
|
||||
else
|
||||
table.insert(nr, {
|
||||
x = -rule.z,
|
||||
y = rule.y,
|
||||
z = rule.x})
|
||||
end
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
@ -633,20 +618,11 @@ end
|
||||
function mesecon.rotate_rules_left(rules)
|
||||
local nr = {}
|
||||
for i, rule in ipairs(rules) do
|
||||
if rule.sx then
|
||||
table.insert(nr, {
|
||||
x = rule.z,
|
||||
y = rule.y,
|
||||
z = -rule.x,
|
||||
sx = rule.sz,
|
||||
sy = rule.sy,
|
||||
sz = -rule.sx})
|
||||
else
|
||||
table.insert(nr, {
|
||||
x = rule.z,
|
||||
y = rule.y,
|
||||
z = -rule.x})
|
||||
end
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
@ -654,20 +630,11 @@ end
|
||||
function mesecon.rotate_rules_down(rules)
|
||||
local nr = {}
|
||||
for i, rule in ipairs(rules) do
|
||||
if rule.sx then
|
||||
table.insert(nr, {
|
||||
x = -rule.y,
|
||||
y = rule.x,
|
||||
z = rule.z,
|
||||
sx = -rule.sy,
|
||||
sy = rule.sx,
|
||||
sz = rule.sz})
|
||||
else
|
||||
table.insert(nr, {
|
||||
x = -rule.y,
|
||||
y = rule.x,
|
||||
z = rule.z})
|
||||
end
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
@ -675,20 +642,11 @@ end
|
||||
function mesecon.rotate_rules_up(rules)
|
||||
local nr = {}
|
||||
for i, rule in ipairs(rules) do
|
||||
if rule.sx then
|
||||
table.insert(nr, {
|
||||
x = rule.y,
|
||||
y = -rule.x,
|
||||
z = rule.z,
|
||||
sx = rule.sy,
|
||||
sy = -rule.sx,
|
||||
sz = rule.sz})
|
||||
else
|
||||
table.insert(nr, {
|
||||
x = rule.y,
|
||||
y = -rule.x,
|
||||
z = rule.z})
|
||||
end
|
||||
name = rule.name})
|
||||
end
|
||||
return nr
|
||||
end
|
||||
|
@ -27,12 +27,27 @@ mesecon.on_placenode = function (pos, node)
|
||||
|
||||
-- Effectors: Send changesignal and activate or deactivate
|
||||
if mesecon.is_effector(node.name) then
|
||||
if mesecon.is_powered(pos) then
|
||||
mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "on", 1)
|
||||
mesecon.activate(pos, node, nil, 1)
|
||||
local powered_rules = {}
|
||||
local unpowered_rules = {}
|
||||
|
||||
-- for each input rule, check if powered
|
||||
for _, r in ipairs(mesecon.effector_get_rules(node)) do
|
||||
local powered = mesecon.is_powered(pos, r)
|
||||
if powered then table.insert(powered_rules, r)
|
||||
else table.insert(unpowered_rules, r) end
|
||||
|
||||
local state = powered and mesecon.state.on or mesecon.state.off
|
||||
mesecon.changesignal(pos, node, r, state, 1)
|
||||
end
|
||||
|
||||
if (#powered_rules > 0) then
|
||||
for _, r in ipairs(powered_rules) do
|
||||
mesecon.activate(pos, node, r, 1)
|
||||
end
|
||||
else
|
||||
mesecon.changesignal(pos, node, mesecon.effector_get_rules(node), "off", 1)
|
||||
mesecon.deactivate(pos, node, nil, 1)
|
||||
for _, r in ipairs(unpowered_rules) do
|
||||
mesecon.deactivate(pos, node, r, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -62,7 +62,7 @@ function mesecon.rule2bit(findrule, allrules)
|
||||
end
|
||||
for m,metarule in ipairs( allrules) do
|
||||
for _, rule in ipairs(metarule ) do
|
||||
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
|
||||
if mesecon.cmpPos(findrule, rule) then
|
||||
return m
|
||||
end
|
||||
end
|
||||
@ -82,7 +82,7 @@ function mesecon.rule2metaindex(findrule, allrules)
|
||||
|
||||
for m, metarule in ipairs( allrules) do
|
||||
for _, rule in ipairs(metarule ) do
|
||||
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
|
||||
if mesecon.cmpPos(findrule, rule) then
|
||||
return m
|
||||
end
|
||||
end
|
||||
@ -153,7 +153,7 @@ function mesecon.set_bit(binary,bit,value)
|
||||
end
|
||||
|
||||
function mesecon.invertRule(r)
|
||||
return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
|
||||
return {x = -r.x, y = -r.y, z = -r.z}
|
||||
end
|
||||
|
||||
function mesecon.addPosRule(p, r)
|
||||
@ -164,10 +164,6 @@ function mesecon.cmpPos(p1, p2)
|
||||
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
|
||||
end
|
||||
|
||||
function mesecon.cmpSpecial(r1, r2)
|
||||
return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
|
||||
end
|
||||
|
||||
function mesecon.tablecopy(table) -- deep table copy
|
||||
if type(table) ~= "table" then return table end -- no need to copy
|
||||
local newtable = {}
|
||||
|
@ -1,222 +1,124 @@
|
||||
function gate_rotate_rules(node)
|
||||
local nodebox = {
|
||||
type = "fixed",
|
||||
fixed = {{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 }},
|
||||
}
|
||||
|
||||
local function gate_rotate_rules(node, rules)
|
||||
for rotations = 0, node.param2 - 1 do
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
function gate_get_output_rules(node)
|
||||
rules = {{x=1, y=0, z=0}}
|
||||
return gate_rotate_rules(node)
|
||||
local function gate_get_output_rules(node)
|
||||
return gate_rotate_rules(node, {{x=1, y=0, z=0}})
|
||||
end
|
||||
|
||||
function gate_get_input_rules_oneinput(node)
|
||||
rules = {{x=-1, y=0, z=0}, {x=1, y=0, z=0}}
|
||||
return gate_rotate_rules(node)
|
||||
local function gate_get_input_rules_oneinput(node)
|
||||
return gate_rotate_rules(node, {{x=-1, y=0, z=0}})
|
||||
end
|
||||
|
||||
function gate_get_input_rules_twoinputs(node)
|
||||
rules = {
|
||||
{x=0, y=0, z=1},
|
||||
{x=0, y=0, z=-1},
|
||||
{x=1, y=0, z=0}}
|
||||
return gate_rotate_rules(node)
|
||||
local function gate_get_input_rules_twoinputs(node)
|
||||
return gate_rotate_rules(node, {{x=0, y=0, z=1, name="input1"},
|
||||
{x=0, y=0, z=-1, name="input2"}})
|
||||
end
|
||||
|
||||
function update_gate(pos, node, rulename, newstate)
|
||||
yc_update_real_portstates(pos, node, rulename, newstate)
|
||||
gate = get_gate(pos)
|
||||
L = rotate_ports(
|
||||
yc_get_real_portstates(pos),
|
||||
minetest.get_node(pos).param2
|
||||
)
|
||||
if gate == "diode" then
|
||||
set_gate(pos, L.a)
|
||||
elseif gate == "not" then
|
||||
set_gate(pos, not L.a)
|
||||
elseif gate == "nand" then
|
||||
set_gate(pos, not(L.b and L.d))
|
||||
elseif gate == "and" then
|
||||
set_gate(pos, L.b and L.d)
|
||||
elseif gate == "xor" then
|
||||
set_gate(pos, (L.b and not L.d) or (not L.b and L.d))
|
||||
end
|
||||
end
|
||||
local function set_gate(pos, node, state)
|
||||
local gate = minetest.registered_nodes[node.name]
|
||||
|
||||
function set_gate(pos, on)
|
||||
gate = get_gate(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if on ~= gate_state(pos) then
|
||||
if mesecon.do_overheat(pos) then
|
||||
pop_gate(pos)
|
||||
else
|
||||
local node = minetest.get_node(pos)
|
||||
if on then
|
||||
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_on", param2=node.param2})
|
||||
mesecon.receptor_on(pos,
|
||||
gate_get_output_rules(node))
|
||||
else
|
||||
minetest.swap_node(pos, {name = "mesecons_gates:"..gate.."_off", param2=node.param2})
|
||||
mesecon.receptor_off(pos,
|
||||
gate_get_output_rules(node))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function get_gate(pos)
|
||||
return minetest.registered_nodes[minetest.get_node(pos).name].mesecons_gate
|
||||
end
|
||||
|
||||
function gate_state(pos)
|
||||
name = minetest.get_node(pos).name
|
||||
return string.find(name, "_on") ~= nil
|
||||
end
|
||||
|
||||
function pop_gate(pos)
|
||||
gate = get_gate(pos)
|
||||
minetest.remove_node(pos)
|
||||
minetest.after(0.2, function (pos)
|
||||
mesecon.receptor_off(pos, mesecon.rules.flat)
|
||||
end , pos) -- wait for pending parsings
|
||||
minetest.add_item(pos, "mesecons_gates:"..gate.."_off")
|
||||
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
||||
minetest.add_item(pos, gate.drop)
|
||||
elseif state then
|
||||
minetest.swap_node(pos, {name = gate.onstate, param2=node.param2})
|
||||
mesecon.receptor_on(pos, gate_get_output_rules(node))
|
||||
else
|
||||
minetest.swap_node(pos, {name = gate.offstate, param2=node.param2})
|
||||
mesecon.receptor_off(pos, gate_get_output_rules(node))
|
||||
end
|
||||
end
|
||||
|
||||
function rotate_ports(L, param2)
|
||||
for rotations=0, param2-1 do
|
||||
port = L.a
|
||||
L.a = L.b
|
||||
L.b = L.c
|
||||
L.c = L.d
|
||||
L.d = port
|
||||
end
|
||||
return L
|
||||
end
|
||||
local function update_gate(pos, node, link, newstate)
|
||||
local gate = minetest.registered_nodes[node.name]
|
||||
|
||||
gates = {
|
||||
{name = "diode", inputnumber = 1},
|
||||
{name = "not" , inputnumber = 1},
|
||||
{name = "nand" , inputnumber = 2},
|
||||
{name = "and" , inputnumber = 2},
|
||||
{name = "xor" , inputnumber = 2}}
|
||||
|
||||
local onoff, drop, nodename, description, groups
|
||||
for _, gate in ipairs(gates) do
|
||||
if gate.inputnumber == 1 then
|
||||
get_rules = gate_get_input_rules_oneinput
|
||||
set_gate(pos, node, gate.assess(newstate == "on"))
|
||||
elseif gate.inputnumber == 2 then
|
||||
get_rules = gate_get_input_rules_twoinputs
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int(link.name, newstate == "on" and 1 or 0)
|
||||
|
||||
local val1 = meta:get_int("input1") == 1
|
||||
local val2 = meta:get_int("input2") == 1
|
||||
set_gate(pos, node, gate.assess(val1, val2))
|
||||
end
|
||||
for on = 0, 1 do
|
||||
nodename = "mesecons_gates:"..gate.name
|
||||
if on == 1 then
|
||||
onoff = "on"
|
||||
drop = nodename.."_off"
|
||||
nodename = nodename.."_"..onoff
|
||||
description = "You hacker you!"
|
||||
groups = {dig_immediate=2, not_in_creative_inventory=1, overheat = 1}
|
||||
else
|
||||
onoff = "off"
|
||||
drop = nil
|
||||
nodename = nodename.."_"..onoff
|
||||
description = gate.name.." Gate"
|
||||
groups = {dig_immediate=2, overheat = 1}
|
||||
end
|
||||
|
||||
tiles = "jeija_microcontroller_bottom.png^"..
|
||||
"jeija_gate_"..onoff..".png^"..
|
||||
"jeija_gate_"..gate.name..".png"
|
||||
function register_gate(name, inputnumber, assess, recipe)
|
||||
local get_inputrules = inputnumber == 2 and gate_get_input_rules_twoinputs or
|
||||
gate_get_input_rules_oneinput
|
||||
local description = "Mesecons Logic Gate: "..name
|
||||
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16 },
|
||||
},
|
||||
}
|
||||
|
||||
local mesecon_state
|
||||
if on == 1 then
|
||||
mesecon_state = mesecon.state.on
|
||||
else
|
||||
mesecon_state = mesecon.state.off
|
||||
end
|
||||
|
||||
minetest.register_node(nodename, {
|
||||
local basename = "mesecons_gates:"..name
|
||||
mesecon.register_node(basename, {
|
||||
description = description,
|
||||
inventory_image = "jeija_gate_off.png^jeija_gate_"..name..".png",
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
drawtype = "nodebox",
|
||||
tiles = {tiles},
|
||||
inventory_image = tiles,
|
||||
selection_box = node_box,
|
||||
node_box = node_box,
|
||||
drop = basename.."_off",
|
||||
selection_box = nodebox,
|
||||
node_box = nodebox,
|
||||
walkable = true,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
update_gate(pos)
|
||||
end,
|
||||
groups = groups,
|
||||
drop = drop,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
mesecons_gate = gate.name,
|
||||
mesecons =
|
||||
{
|
||||
receptor =
|
||||
{
|
||||
state = mesecon_state,
|
||||
assess = assess,
|
||||
onstate = basename.."_on",
|
||||
offstate = basename.."_off",
|
||||
inputnumber = inputnumber
|
||||
},{
|
||||
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_off.png^"..
|
||||
"jeija_gate_"..name..".png"},
|
||||
groups = {dig_immediate = 2},
|
||||
mesecons = { receptor = {
|
||||
state = "off",
|
||||
rules = gate_get_output_rules
|
||||
},
|
||||
effector =
|
||||
{
|
||||
rules = get_rules,
|
||||
}, effector = {
|
||||
rules = get_inputrules,
|
||||
action_change = update_gate
|
||||
}
|
||||
}
|
||||
}}
|
||||
},{
|
||||
tiles = {"jeija_microcontroller_bottom.png^".."jeija_gate_on.png^"..
|
||||
"jeija_gate_"..name..".png"},
|
||||
groups = {dig_immediate = 2, not_in_creative_inventory = 1},
|
||||
mesecons = { receptor = {
|
||||
state = "on",
|
||||
rules = gate_get_output_rules
|
||||
}, effector = {
|
||||
rules = get_inputrules,
|
||||
action_change = update_gate
|
||||
}}
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({output = basename.."_off", recipe = recipe})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'mesecons_gates:diode_off',
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons_torch:mesecon_torch_on'},
|
||||
{'', '', ''},
|
||||
},
|
||||
})
|
||||
register_gate("diode", 1, function (input) return input end,
|
||||
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons_torch:mesecon_torch_on"}})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'mesecons_gates:not_off',
|
||||
recipe = {
|
||||
{'', '', ''},
|
||||
{'mesecons:mesecon', 'mesecons_torch:mesecon_torch_on', 'mesecons:mesecon'},
|
||||
{'', '', ''},
|
||||
},
|
||||
})
|
||||
register_gate("not", 1, function (input) return not input end,
|
||||
{{"mesecons:mesecon", "mesecons_torch:mesecon_torch_on", "mesecons:mesecon"}})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'mesecons_gates:and_off',
|
||||
recipe = {
|
||||
{'mesecons:mesecon', '', ''},
|
||||
{'', 'mesecons_materials:silicon', 'mesecons:mesecon'},
|
||||
{'mesecons:mesecon', '', ''},
|
||||
},
|
||||
})
|
||||
register_gate("and", 2, function (val1, val2) return val1 and val2 end,
|
||||
{{"mesecons:mesecon", "", ""},
|
||||
{"", "mesecons_materials:silicon", "mesecons:mesecon"},
|
||||
{"mesecons:mesecon", "", ""}})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'mesecons_gates:nand_off',
|
||||
recipe = {
|
||||
{'mesecons:mesecon', '', ''},
|
||||
{'', 'mesecons_materials:silicon', 'mesecons_torch:mesecon_torch_on'},
|
||||
{'mesecons:mesecon', '', ''},
|
||||
},
|
||||
})
|
||||
register_gate("nand", 2, function (val1, val2) return not (val1 and val2) end,
|
||||
{{"mesecons:mesecon", "", ""},
|
||||
{"", "mesecons_materials:silicon", "mesecons_torch:mesecon_torch_on"},
|
||||
{"mesecons:mesecon", "", ""}})
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'mesecons_gates:xor_off',
|
||||
recipe = {
|
||||
{'mesecons:mesecon', '', ''},
|
||||
{'', 'mesecons_materials:silicon', 'mesecons_materials:silicon'},
|
||||
{'mesecons:mesecon', '', ''},
|
||||
},
|
||||
})
|
||||
register_gate("xor", 2, function (val1, val2) return (val1 or val2) and not (val1 and val2) end,
|
||||
{{"mesecons:mesecon", "", ""},
|
||||
{"", "mesecons_materials:silicon", "mesecons_materials:silicon"},
|
||||
{"mesecons:mesecon", "", ""}})
|
||||
|
@ -94,7 +94,7 @@ function mesecon.mvps_push(pos, dir, maximum) -- pos: pos of mvps; dir: directio
|
||||
|
||||
-- add nodes
|
||||
for _, n in ipairs(nodes) do
|
||||
np = mesecon.addPosRule(n.pos, dir)
|
||||
local np = mesecon.addPosRule(n.pos, dir)
|
||||
minetest.add_node(np, n.node)
|
||||
minetest.get_meta(np):from_table(n.meta)
|
||||
end
|
||||
@ -123,8 +123,8 @@ mesecon.register_on_mvps_move(function(moved_nodes)
|
||||
end)
|
||||
|
||||
function mesecon.mvps_pull_single(pos, dir) -- pos: pos of mvps; direction: direction of pull (matches push direction for sticky pistons)
|
||||
np = mesecon.addPosRule(pos, dir)
|
||||
nn = minetest.get_node(np)
|
||||
local np = mesecon.addPosRule(pos, dir)
|
||||
local nn = minetest.get_node(np)
|
||||
|
||||
if ((not minetest.registered_nodes[nn.name]) --unregistered node
|
||||
or minetest.registered_nodes[nn.name].liquidtype == "none") --non-liquid node
|
||||
|
@ -55,8 +55,8 @@ piston_get_direction = function(dir, node)
|
||||
end
|
||||
|
||||
local piston_remove_pusher = function(pos, node)
|
||||
pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pusherpos = mesecon.addPosRule(pos, dir)
|
||||
local pushername = minetest.get_node(pusherpos).name
|
||||
|
||||
@ -100,9 +100,9 @@ local piston_off = function(pos, node)
|
||||
piston_remove_pusher(pos, node)
|
||||
|
||||
if pistonspec.sticky then
|
||||
dir = piston_get_direction(pistonspec.dir, node)
|
||||
pullpos = mesecon.addPosRule(pos, dir)
|
||||
stack = mesecon.mvps_pull_single(pullpos, dir)
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pullpos = mesecon.addPosRule(pos, dir)
|
||||
local stack = mesecon.mvps_pull_single(pullpos, dir)
|
||||
mesecon.mvps_process_stack(pos, dir, stack)
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user