mesecons/mesecons/util.lua

236 lines
5.1 KiB
Lua
Raw Normal View History

function mesecon.move_node(pos, newpos)
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:
mesecon.flattenrules(allrules)
mesecon.rule2bit(findrule, allrules)
mesecon.rule2meta(findrule, allrules)
2013-06-20 04:38:34 +02:00
dec2bin(n)
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
--]]
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
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
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
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
return nil
2013-06-20 04:38:34 +02:00
end
if not(findrule) then
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
if mesecon.cmpPos(findrule, rule) and mesecon.cmpSpecial(findrule, rule) then
return m
2013-06-20 04:38:34 +02:00
end
end
end
end
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
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
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
function mesecon.getbinstate(nodename, states)
return dec2bin(mesecon.getstate(nodename, states)-1)
2013-06-20 04:38:34 +02:00
end
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
function mesecon.set_bit(binary,bit,value)
2013-06-20 04:38:34 +02:00
if value == "1" then
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
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
function mesecon.invertRule(r)
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
function mesecon.addPosRule(p, r)
return {x = p.x + r.x, y = p.y + r.y, z = p.z + r.z}
end
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 = {}
for idx, item in pairs(table) do
if type(item) == "table" then
newtable[idx] = mesecon.tablecopy(item)
else
newtable[idx] = item
end
end
return newtable
end
function mesecon.cmpAny(t1, t2)
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
if not mesecon.cmpAny(e, t2[i]) then return false end
end
return true
end
-- does not overwrite values; number keys (ipairs) are appended, not overwritten
function mesecon.mergetable(source, dest)
local rval = mesecon.tablecopy(dest)
for k, v in pairs(source) do
rval[k] = dest[k] or mesecon.tablecopy(v)
end
for i, v in ipairs(source) do
table.insert(rval, mesecon.tablecopy(v))
end
return rval
end
function mesecon.register_node(name, spec_common, spec_off, spec_on)
spec_common.drop = spec_common.drop or name .. "_off"
spec_common.__mesecon_basename = name
spec_on.__mesecon_state = "on"
spec_off.__mesecon_state = "off"
spec_on = mesecon.mergetable(spec_common, spec_on);
spec_off = mesecon.mergetable(spec_common, spec_off);
minetest.register_node(name .. "_on", spec_on)
minetest.register_node(name .. "_off", spec_off)
end
-- 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