function table.indexof(arr,x) for i,v in ipairs(arr) do if v == x then return i end end end function table.arrperm(arr1,arr2) out = {} for i,v in ipairs(arr1) do table.insert(out,table.indexof(arr2,v)) end return out end function table.invert(arr) out = {} for k,v in pairs(arr) do out[v] = k end return out end function table.getkey1(arr,x) for k,v in pairs(arr) do if table.equals1(x,v) then return k end end end function table.length(arr) local c = 0 for k,v in pairs(arr) do c = c + 1 end return c end function string.startsWith(str,ex) return string.sub(str,1,string.len(ex)) == ex end function string.without(str,ex) return string.sub(str,string.len(ex)+1,-1) end function string.endsWith(str,ex) return string.sub(str,-1-string.len(ex),-1) == ex end function string.without2(str,ex,ex2) return string.sub(str,string.len(ex)+1,-1-string.len(ex2)) end function table.equals1(arr1,arr2) for i,v in pairs(arr1) do if arr2[i] ~= v then return false end end return #arr1 == #arr2 end local function nodeboxDistance(nb,p) return (((nb[1] < p[1]) and (p[1] - nb[1])) or ((p[1] < nb[4]) and (nb[4] - p[1])) or 0) + (((nb[2] < p[2]) and (p[2] - nb[2])) or ((p[2] < nb[5]) and (nb[5] - p[2])) or 0) + (((nb[3] < p[3]) and (p[3] - nb[3])) or ((p[3] < nb[6]) and (nb[6] - p[3])) or 0) end function logikraft.nearestNodeboxIndex(nodeboxes,point) local minindex=-1 local minvalue = 9999 for i,nb in ipairs(nodeboxes) do local d = nodeboxDistance(nb,point) if d < minvalue then minvalue = d minindex = i end end return minindex end function logikraft.lookingAtNbIndex(user,under) local range=15 local eye = vector.add(user:get_pos(),{x=0,y=1.625,z=0}) local objective = vector.add(eye, vector.multiply(user:get_look_dir(),range)) local ray = minetest.raycast(eye,objective,false,false) for p in ray do if p.under.x==under.x and p.under.y==under.y and p.under.z==under.z then return p.box_id end end return 0 end function logikraft.vecTo8dir(vec) local x = vec[1] local z = vec[3] return x<0 and z>=0 and -z<=x and 0 or x>=0 and z>=0 and z>x and 1 or x>=0 and z>=0 and z<=x and 2 or x>=0 and z<0 and -z=0 and z<0 and -z>=x and 4 or x<0 and z<0 and z=x and 6 or x<0 and z>=0 and -z>x and 7 or 0 -- Should not happen end function logikraft.dir8to4(dir) return math.floor(dir / 2) end function logikraft.addToPos8dir(dir,pos,w,h) local x = pos[1] local y = pos[2] local z = pos[3] return dir == 0 and {x = x-w, y = y, z = z+h} or dir == 1 and {x = x+w, y = y, z = z+h} or dir == 2 and {x = x+h, y = y, z = z+w} or dir == 3 and {x = x+h, y = y, z = z-w} or dir == 4 and {x = x+w, y = y, z = z-h} or dir == 5 and {x = x-w, y = y, z = z-h} or dir == 6 and {x = x-h, y = y, z = z-w} or dir == 7 and {x = x-h, y = y, z = z+w} or pos -- Should not happen end function logikraft.addToPos4dir(dir,pos,w,h) return logikraft.addToPos8dir(dir*2+1,pos,w,h) end function table.findMatch(ta,tb) do for i,x in ipairs(ta) do for j,y in ipairs(tb) do if x == y then return {i,j} end end end end return nil end function table.findMatch1(ta,tb) do for i,x in ipairs(ta) do for j,y in ipairs(tb) do if table.equals1(x,y) then return {i,j} end end end end return nil end function logikraft.rotateNodebox(nb,rot) return (math.fmod(rot,4)==0) and {nb[1],nb[2],nb[3],nb[4],nb[5],nb[6]} or (math.fmod(rot,4)==1) and {nb[3],nb[2],-nb[1],nb[6],nb[5],-nb[4]} or (math.fmod(rot,4)==2) and {-nb[1],nb[2],-nb[3],-nb[4],nb[5],-nb[6]} or (math.fmod(rot,4)==3) and {-nb[3],nb[2],nb[1],-nb[6],nb[5],nb[4]} or nb -- Should not happen end function logikraft.rotate4dir(conn,r) local function rotate4dirOnce(conn) return math.floor(conn/2) + 8*math.fmod(conn,2) end local x = math.fmod(conn,16) for i=1,r do x = rotate4dirOnce(x) end return (conn - math.fmod(conn,16) + x) end function table.constTable(val,size) local t = {} for i=1,size do table.insert(t,val) end return t end