2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.move_node(pos, newpos)
|
2013-12-01 04:13:00 +01:00
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
local meta = minetest.get_meta(pos):to_table()
|
|
|
|
minetest.remove_node(pos)
|
|
|
|
minetest.add_node(newpos, node)
|
|
|
|
minetest.get_meta(pos):from_table(meta)
|
2012-12-16 11:58:43 +01:00
|
|
|
end
|
|
|
|
|
2013-06-20 04:38:34 +02:00
|
|
|
--[[ new functions:
|
2014-11-22 15:42:22 +01:00
|
|
|
mesecon.flattenrules(allrules)
|
|
|
|
mesecon.rule2bit(findrule, allrules)
|
|
|
|
mesecon.rule2meta(findrule, allrules)
|
2013-06-20 04:38:34 +02:00
|
|
|
dec2bin(n)
|
2014-11-22 15:42:22 +01:00
|
|
|
mesecon.getstate(nodename, states)
|
|
|
|
mesecon.getbinstate(nodename, states)
|
|
|
|
mesecon.get_bit(binary, bit)
|
|
|
|
mesecon.set_bit(binary, bit, value)
|
|
|
|
mesecon.invertRule(r)
|
2013-06-20 04:38:34 +02:00
|
|
|
--]]
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.flattenrules(allrules)
|
2013-06-20 04:38:34 +02:00
|
|
|
--[[
|
|
|
|
{
|
|
|
|
{
|
|
|
|
{xyz},
|
|
|
|
{xyz},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
{xyz},
|
|
|
|
{xyz},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
--]]
|
|
|
|
if allrules[1] and
|
|
|
|
allrules[1].x then
|
|
|
|
return allrules
|
|
|
|
end
|
|
|
|
|
|
|
|
local shallowrules = {}
|
|
|
|
for _, metarule in ipairs( allrules) do
|
|
|
|
for _, rule in ipairs(metarule ) do
|
|
|
|
table.insert(shallowrules, rule)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return shallowrules
|
|
|
|
--[[
|
|
|
|
{
|
|
|
|
{xyz},
|
|
|
|
{xyz},
|
|
|
|
{xyz},
|
|
|
|
{xyz},
|
|
|
|
}
|
|
|
|
--]]
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.rule2bit(findrule, allrules)
|
2013-06-20 04:38:34 +02:00
|
|
|
--get the bit of the metarule the rule is in, or bit 1
|
|
|
|
if (allrules[1] and
|
|
|
|
allrules[1].x) or
|
|
|
|
not findrule then
|
|
|
|
return 1
|
|
|
|
end
|
|
|
|
for m,metarule in ipairs( allrules) do
|
|
|
|
for _, rule in ipairs(metarule ) do
|
2014-11-22 15:42:22 +01:00
|
|
|
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
|
2013-06-20 04:38:34 +02:00
|
|
|
return m
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.rule2metaindex(findrule, allrules)
|
2013-06-20 04:38:34 +02:00
|
|
|
--get the metarule the rule is in, or allrules
|
|
|
|
|
|
|
|
if allrules[1].x then
|
2014-01-04 15:52:52 +01:00
|
|
|
return nil
|
2013-06-20 04:38:34 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
if not(findrule) then
|
2014-11-22 15:42:22 +01:00
|
|
|
return mesecon.flattenrules(allrules)
|
2013-06-20 04:38:34 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
for m, metarule in ipairs( allrules) do
|
|
|
|
for _, rule in ipairs(metarule ) do
|
2014-11-22 15:42:22 +01:00
|
|
|
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
|
2014-01-04 15:52:52 +01:00
|
|
|
return m
|
2013-06-20 04:38:34 +02:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.rule2meta(findrule, allrules)
|
|
|
|
local index = mesecon.rule2metaindex(findrule, allrules)
|
2014-01-04 16:51:52 +01:00
|
|
|
if index == nil then
|
|
|
|
if allrules[1].x then
|
|
|
|
return allrules
|
|
|
|
else
|
|
|
|
return {}
|
|
|
|
end
|
|
|
|
end
|
2014-01-04 15:52:52 +01:00
|
|
|
return allrules[index]
|
|
|
|
end
|
|
|
|
|
2013-06-20 04:38:34 +02:00
|
|
|
if convert_base then
|
|
|
|
print(
|
|
|
|
"base2dec is tonumber(num,base1)\n"..
|
|
|
|
"commonlib needs dec2base(num,base2)\n"..
|
|
|
|
"and it needs base2base(num,base1,base2),\n"..
|
|
|
|
"which is dec2base(tonumber(num,base1),base2)"
|
|
|
|
)
|
|
|
|
else
|
|
|
|
function dec2bin(n)
|
|
|
|
local x, y = math.floor(n / 2), n % 2
|
|
|
|
if (n > 1) then
|
|
|
|
return dec2bin(x)..y
|
|
|
|
else
|
|
|
|
return ""..y
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.getstate(nodename, states)
|
2013-06-20 04:38:34 +02:00
|
|
|
for state, name in ipairs(states) do
|
|
|
|
if name == nodename then
|
|
|
|
return state
|
|
|
|
end
|
|
|
|
end
|
|
|
|
error(nodename.." doesn't mention itself in "..dump(states))
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.getbinstate(nodename, states)
|
|
|
|
return dec2bin(mesecon.getstate(nodename, states)-1)
|
2013-06-20 04:38:34 +02:00
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.get_bit(binary,bit)
|
2013-06-20 04:38:34 +02:00
|
|
|
bit = bit or 1
|
|
|
|
local c = binary:len()-(bit-1)
|
|
|
|
return binary:sub(c,c) == "1"
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.set_bit(binary,bit,value)
|
2013-06-20 04:38:34 +02:00
|
|
|
if value == "1" then
|
2014-11-22 15:42:22 +01:00
|
|
|
if not mesecon.get_bit(binary,bit) then
|
2013-06-20 04:38:34 +02:00
|
|
|
return dec2bin(tonumber(binary,2)+math.pow(2,bit-1))
|
|
|
|
end
|
|
|
|
elseif value == "0" then
|
2014-11-22 15:42:22 +01:00
|
|
|
if mesecon.get_bit(binary,bit) then
|
2013-06-20 04:38:34 +02:00
|
|
|
return dec2bin(tonumber(binary,2)-math.pow(2,bit-1))
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return binary
|
|
|
|
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.invertRule(r)
|
2014-01-04 15:52:52 +01:00
|
|
|
return {x = -r.x, y = -r.y, z = -r.z, sx = r.sx, sy = r.sy, sz = r.sz}
|
2013-06-20 04:38:34 +02:00
|
|
|
end
|
2012-12-16 11:58:43 +01:00
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.addPosRule(p, r)
|
2012-12-08 21:56:09 +01:00
|
|
|
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.cmpPos(p1, p2)
|
2012-12-08 21:56:09 +01:00
|
|
|
return (p1.x == p2.x and p1.y == p2.y and p1.z == p2.z)
|
|
|
|
end
|
2013-04-02 11:56:37 +02:00
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.cmpSpecial(r1, r2)
|
2014-01-04 15:52:52 +01:00
|
|
|
return (r1.sx == r2.sx and r1.sy == r2.sy and r1.sz == r2.sz)
|
|
|
|
end
|
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.tablecopy(table) -- deep table copy
|
2014-01-11 10:04:32 +01:00
|
|
|
if type(table) ~= "table" then return table end -- no need to copy
|
2013-04-02 11:56:37 +02:00
|
|
|
local newtable = {}
|
|
|
|
|
|
|
|
for idx, item in pairs(table) do
|
|
|
|
if type(item) == "table" then
|
2014-11-22 15:42:22 +01:00
|
|
|
newtable[idx] = mesecon.tablecopy(item)
|
2013-04-02 11:56:37 +02:00
|
|
|
else
|
|
|
|
newtable[idx] = item
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return newtable
|
|
|
|
end
|
2014-01-10 22:29:18 +01:00
|
|
|
|
2014-11-22 15:42:22 +01:00
|
|
|
function mesecon.cmpAny(t1, t2)
|
2014-01-10 22:29:18 +01:00
|
|
|
if type(t1) ~= type(t2) then return false end
|
|
|
|
if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
|
|
|
|
|
|
|
|
for i, e in pairs(t1) do
|
2014-11-22 15:42:22 +01:00
|
|
|
if not mesecon.cmpAny(e, t2[i]) then return false end
|
2014-01-10 22:29:18 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
2014-11-22 11:37:47 +01:00
|
|
|
|
2014-11-22 16:00:49 +01:00
|
|
|
-- does not overwrite values; number keys (ipairs) are appended, not overwritten
|
2014-11-22 20:49:54 +01:00
|
|
|
function mesecon.mergetable(source, dest)
|
2014-11-22 17:12:48 +01:00
|
|
|
local rval = mesecon.tablecopy(dest)
|
|
|
|
|
2014-11-22 11:37:47 +01:00
|
|
|
for k, v in pairs(source) do
|
2014-11-22 17:12:48 +01:00
|
|
|
rval[k] = dest[k] or mesecon.tablecopy(v)
|
2014-11-22 11:37:47 +01:00
|
|
|
end
|
2014-11-22 12:28:45 +01:00
|
|
|
for i, v in ipairs(source) do
|
2014-11-22 17:12:48 +01:00
|
|
|
table.insert(rval, mesecon.tablecopy(v))
|
2014-11-22 12:28:45 +01:00
|
|
|
end
|
2014-11-22 17:12:48 +01:00
|
|
|
|
|
|
|
return rval
|
2014-11-22 11:37:47 +01:00
|
|
|
end
|
|
|
|
|
2014-11-22 20:49:54 +01:00
|
|
|
function mesecon.register_node(name, spec_common, spec_off, spec_on)
|
2014-11-22 11:37:47 +01:00
|
|
|
spec_common.drop = spec_common.drop or name .. "_off"
|
2014-11-22 20:49:54 +01:00
|
|
|
spec_common.__mesecon_basename = name
|
|
|
|
spec_on.__mesecon_state = "on"
|
|
|
|
spec_off.__mesecon_state = "off"
|
2014-11-22 11:37:47 +01:00
|
|
|
|
2014-11-22 17:12:48 +01:00
|
|
|
spec_on = mesecon.mergetable(spec_common, spec_on);
|
|
|
|
spec_off = mesecon.mergetable(spec_common, spec_off);
|
2014-11-22 11:37:47 +01:00
|
|
|
|
|
|
|
minetest.register_node(name .. "_on", spec_on)
|
|
|
|
minetest.register_node(name .. "_off", spec_off)
|
|
|
|
end
|
2014-11-22 20:49:54 +01:00
|
|
|
|
|
|
|
-- swap onstate and offstate nodes, returns new state
|
|
|
|
function mesecon.flipstate(pos, node)
|
|
|
|
local nodedef = minetest.registered_nodes[node.name]
|
|
|
|
local newstate
|
|
|
|
if (nodedef.__mesecon_state == "on") then newstate = "off" end
|
|
|
|
if (nodedef.__mesecon_state == "off") then newstate = "on" end
|
|
|
|
|
|
|
|
minetest.swap_node(pos, {name = nodedef.__mesecon_basename .. "_" .. newstate,
|
|
|
|
param2 = node.param2})
|
|
|
|
|
|
|
|
return newstate
|
|
|
|
end
|