129 lines
3.3 KiB
Lua
129 lines
3.3 KiB
Lua
-- 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
|