127 lines
3.9 KiB
Lua
127 lines
3.9 KiB
Lua
local S = minetest.get_translator("lzr_laser")
|
|
|
|
local TEX_LASER, TEX_LASER_NOCENTER
|
|
local ALPHA_LASER
|
|
if lzr_globals.OPAQUE_LASERS then
|
|
TEX_LASER = "lzr_laser_laser_opaque.png"
|
|
TEX_LASER_NOCENTER = "lzr_laser_laser_nocenter_opaque.png"
|
|
ALPHA_LASER = "clip"
|
|
else
|
|
TEX_LASER = "lzr_laser_laser.png"
|
|
TEX_LASER_NOCENTER = "lzr_laser_laser_nocenter.png"
|
|
ALPHA_LASER = "blend"
|
|
end
|
|
|
|
-- 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 = { TEX_LASER, TEX_LASER, "blank.png", "blank.png", TEX_LASER }
|
|
elseif axes_active.y then
|
|
tex = { "blank.png", "blank.png", TEX_LASER }
|
|
else
|
|
tex = { TEX_LASER, TEX_LASER, TEX_LASER, TEX_LASER, "blank.png" }
|
|
end
|
|
elseif axes == 2 then
|
|
if axes_active.x == false then
|
|
tex = { TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER, TEX_LASER, TEX_LASER_NOCENTER }
|
|
elseif axes_active.y == false then
|
|
tex = { TEX_LASER, TEX_LASER, TEX_LASER_NOCENTER }
|
|
else
|
|
tex = { TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER_NOCENTER, TEX_LASER }
|
|
end
|
|
|
|
elseif axes == 3 then
|
|
tex = { TEX_LASER_NOCENTER }
|
|
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 = ALPHA_LASER,
|
|
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
|