-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P local LASER_RADIUS = -1/16 -- DATA FORMATS: --[[ dirstring: A representation of 3 axes (XYZ) which are either 'active' (1) or 'inactive' (0) Each direction has the character "1" or "0". The characters stand for these directions, in order: X, Y, Z Example: "101" ]] --[[ dirs table: Like dirstring, but in table format. It's a table with 3 numbers, each of them being either 1 or 0. The same order of axes is used like for dirstring. Example: { 1, 0, 1 } ]] -- Converts a dirstring to a dirs table function lzr_laser.dirstring_to_dirs(dirstring) local dirs = {} for d=1, 3 do if string.sub(dirstring, d, d) == "1" then dirs[d] = 1 elseif string.sub(dirstring, d, d) == "0" then dirs[d] = 0 else error("[lzr_laser] dirstring_to_dirs: Invalid dirstring!") end end return dirs end -- Converts a dirs table to a dirstring function lzr_laser.dirs_to_dirstring(dirs) local dirstring = "" for d=1, 3 do if dirs[d] == 0 then dirstring = dirstring .. "0" elseif dirs[d] == 1 then dirstring = dirstring .. "1" else error("[lzr_laser] dirs_to_dirstring: Invalid dirs!") end end return dirstring end function lzr_laser.vector_to_dirs(dir_vector) local dirs = {0,0,0} if dir_vector.x ~= 0 then dirs[1] = 1 end if dir_vector.y ~= 0 then dirs[2] = 1 end if dir_vector.z ~= 0 then dirs[3] = 1 end return dirs end -- Convert number to string in binary form -- * num: Number -- * minLength: Minimum number of characters the string must have, will -- fill string with leading zeroes if needed (default: 1) -- Returns: string function lzr_laser.dec2bin(num, minLength) if not minLength then minLength = 1 end local t = {} local rem while num > 0 do rem = math.fmod(num,2) t[#t+1] = rem num = (num-rem)/2 end local bin = table.concat(t) bin = string.reverse(bin) local length = string.len(bin) if length < minLength then bin = string.rep("0", minLength - length) .. bin end return bin end -- Takes 2 binary numbers (as strings!) -- and returns the 'bitwise or' of them (also as string). -- Both strings MUST be of equal length. function lzr_laser.bitwise_or(bin1, bin2) local len = string.len(bin1) local out = "" for i=1, len do if string.sub(bin1, i, i) == "1" or string.sub(bin2, i, i) == "1" then out = out .. "1" else out = out .. "0" end end return out end -- Generates a line of particles between `pos1` and `pos2` with particle texture `particle` function lzr_laser.particle_line(pos1, pos2, particle) local steps = 30 local amount = 10 local spread = 0.1 local vspread = 0.01 local size = 0.4 local pos = vector.copy(pos1) for i=0,steps-1 do pos.x = pos1.x + (pos2.x - pos1.x) * (i/steps) pos.y = pos1.y + (pos2.y - pos1.y) * (i/steps) pos.z = pos1.z + (pos2.z - pos1.z) * (i/steps) minetest.add_particlespawner({ amount = amount, time = 0.001, minpos = vector.subtract(pos, vector.new(spread, spread, spread)), maxpos = vector.add(pos, vector.new(spread, spread, spread)), minvel = vector.new(-vspread, -vspread, -vspread), maxvel = vector.new(vspread, vspread, vspread), minsize = size, maxsize = size, texture = particle, minexptime = 1.5, maxexptime = 1.7, }) end end