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