115 lines
3.9 KiB
Lua
115 lines
3.9 KiB
Lua
local S = minetest.get_translator("lzr_laser")
|
|
|
|
-- Distance from center to side of the laser beam square. Not really the radius, but it sounds cooler. :P
|
|
local LASER_RADIUS = -1/16
|
|
|
|
-- Returns a nodebox for the given dirs table
|
|
local function dirs_to_nodebox(dirs)
|
|
local boxes = {}
|
|
local x = dirs[1] == 1
|
|
local y = dirs[2] == 1
|
|
local z = dirs[3] == 1
|
|
|
|
-- True if 2 or more axes are used
|
|
local multidir = (x and y) or (x and z) or (y and z)
|
|
|
|
-- Center block
|
|
if multidir and (x or y or z) then
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
|
end
|
|
|
|
-- Axes (X, Y, Z)
|
|
if x then
|
|
if not multidir then
|
|
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
|
else
|
|
table.insert(boxes, { -0.5, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, 0.5, LASER_RADIUS, LASER_RADIUS })
|
|
end
|
|
end
|
|
if y then
|
|
if not multidir then
|
|
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
|
else
|
|
table.insert(boxes, { -LASER_RADIUS, -0.5, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, 0.5, LASER_RADIUS })
|
|
end
|
|
end
|
|
if z then
|
|
if not multidir then
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
|
else
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -0.5, LASER_RADIUS, LASER_RADIUS, LASER_RADIUS })
|
|
table.insert(boxes, { -LASER_RADIUS, -LASER_RADIUS, -LASER_RADIUS, LASER_RADIUS, LASER_RADIUS, 0.5 })
|
|
end
|
|
end
|
|
return boxes
|
|
end
|
|
|
|
-- Register laser nodes
|
|
-- 7 nodes because (2^3)-1 (2 states for each of 3 axes, minus the state when there's no laser (=air))
|
|
for i=1, 7 do
|
|
local dirstring = lzr_laser.dec2bin(i, 3)
|
|
local dirs = lzr_laser.dirstring_to_dirs(dirstring)
|
|
|
|
-- Check which textures to render.
|
|
-- This looks complicated but serves a simple purpose: To prevent the laser cross-section
|
|
-- to render, so there is a "clean" laser beam look.
|
|
-- This works because lzr_laser_laser_nocenter.png.
|
|
local axes = 0
|
|
local axes_active = {x=false,y=false,z=false}
|
|
for a=1,3 do
|
|
if dirs[a] ~= 0 then
|
|
axes = axes + 1
|
|
if a == 1 then
|
|
axes_active.x = true
|
|
elseif a == 2 then
|
|
axes_active.y = true
|
|
elseif a == 3 then
|
|
axes_active.z = true
|
|
end
|
|
end
|
|
end
|
|
local tex
|
|
if axes == 1 then
|
|
if axes_active.x then
|
|
tex = { "lzr_laser_laser.png", "lzr_laser_laser.png", "blank.png", "blank.png", "lzr_laser_laser.png" }
|
|
elseif axes_active.y then
|
|
tex = { "blank.png", "blank.png", "lzr_laser_laser.png" }
|
|
else
|
|
tex = { "lzr_laser_laser.png", "lzr_laser_laser.png", "lzr_laser_laser.png", "lzr_laser_laser.png", "blank.png" }
|
|
end
|
|
elseif axes == 2 then
|
|
if axes_active.x == false then
|
|
tex = { "lzr_laser_laser_nocenter.png", "lzr_laser_laser_nocenter.png", "lzr_laser_laser.png", "lzr_laser_laser.png", "lzr_laser_laser_nocenter.png" }
|
|
elseif axes_active.y == false then
|
|
tex = { "lzr_laser_laser.png", "lzr_laser_laser.png", "lzr_laser_laser_nocenter.png" }
|
|
else
|
|
tex = { "lzr_laser_laser_nocenter.png", "lzr_laser_laser_nocenter.png", "lzr_laser_laser_nocenter.png", "lzr_laser_laser_nocenter.png", "lzr_laser_laser.png" }
|
|
end
|
|
|
|
elseif axes == 3 then
|
|
tex = { "lzr_laser_laser_nocenter.png" }
|
|
end
|
|
|
|
-- Finally register the laser
|
|
minetest.register_node("lzr_laser:laser_"..dirstring, {
|
|
description = S("Laser (@1)", dirstring),
|
|
paramtype = "light",
|
|
light_source = lzr_globals.LASER_GLOW,
|
|
drawtype = "nodebox",
|
|
sunlight_propagates = true,
|
|
walkable = false,
|
|
use_texture_alpha = "blend",
|
|
tiles = tex,
|
|
pointable = false,
|
|
buildable_to = true,
|
|
node_box = {
|
|
type = "fixed",
|
|
fixed = dirs_to_nodebox(dirs),
|
|
},
|
|
groups = { laser = i, not_in_creative_inventory = 1 },
|
|
drop = "",
|
|
})
|
|
end
|