local S = minetest.get_translator("lzr_laser") -- List of laser hex codes. Affects the actual laser color in the game! lzr_laser.DEFAULT_LASER_COLORS = { [lzr_globals.COLOR_RED] = "#FF0000", [lzr_globals.COLOR_GREEN] = "#00FF00", [lzr_globals.COLOR_BLUE] = "#0000FF", [lzr_globals.COLOR_YELLOW] = "#FFFF00", [lzr_globals.COLOR_CYAN] = "#00FFFF", [lzr_globals.COLOR_MAGENTA] = "#FF00FF", [lzr_globals.COLOR_WHITE] = "#FFFFFF", } -- List of patterns to apply on lasers to distinguish them by some other -- way than just color. Implemented to deal with colorblindness. local LASER_PATTERNS = { [lzr_globals.COLOR_RED] = nil, -- no pattern, use a solid line [lzr_globals.COLOR_GREEN] = { name = "lzr_laser_pattern_lines.png", size = 16 }, [lzr_globals.COLOR_BLUE] = { name = "lzr_laser_pattern_dots.png", size = 16 }, [lzr_globals.COLOR_YELLOW] = { name = "lzr_laser_pattern_checkers.png", size = 16 }, [lzr_globals.COLOR_CYAN] = { name = "lzr_laser_pattern_long_checkers.png", size = 16 }, [lzr_globals.COLOR_MAGENTA] = { name = "lzr_laser_pattern_alternating.png", size = 16 }, [lzr_globals.COLOR_WHITE] = { name = "lzr_laser_pattern_holes.png", size = 32 }, } -- Hex alpha value for translucent lasers, as a string local LALPHA = "8E" -- Shorthand to generate a laser tile. We don't use texture files, -- we generate them on the fly! local maketile = function(colorcode, alpha) local use_patterns = minetest.settings:get_bool("lzr_patterned_lasers", false) local alpha_append = "" local pattern_append = "" if alpha then alpha_append = LALPHA end local texsize = 16 if use_patterns then local pattern = LASER_PATTERNS[colorcode] if pattern ~= nil then pattern_append = "^[mask:"..pattern.name texsize = pattern.size end end local texture = -- Generate the texture base color "([fill:"..texsize.."x"..texsize..":".. lzr_laser.DEFAULT_LASER_COLORS[colorcode]..alpha_append..")" -- Apply a pattern on the laser, if enabled (allows to distinguish -- lasers other than by color to circumvent colorblindness) .. pattern_append return { name = texture, backface_culling = true } end -- List of all possible laser tiles if lzr_globals.OPAQUE_LASERS then lzr_laser.TILE_LASER_R = maketile(lzr_globals.COLOR_RED) lzr_laser.TILE_LASER_G = maketile(lzr_globals.COLOR_GREEN) lzr_laser.TILE_LASER_B = maketile(lzr_globals.COLOR_BLUE) lzr_laser.TILE_LASER_Y = maketile(lzr_globals.COLOR_YELLOW) lzr_laser.TILE_LASER_C = maketile(lzr_globals.COLOR_CYAN) lzr_laser.TILE_LASER_M = maketile(lzr_globals.COLOR_MAGENTA) lzr_laser.TILE_LASER_W = maketile(lzr_globals.COLOR_WHITE) lzr_laser.ALPHA_LASER = "clip" else lzr_laser.TILE_LASER_R = maketile(lzr_globals.COLOR_RED, true) lzr_laser.TILE_LASER_G = maketile(lzr_globals.COLOR_GREEN, true) lzr_laser.TILE_LASER_B = maketile(lzr_globals.COLOR_BLUE, true) lzr_laser.TILE_LASER_Y = maketile(lzr_globals.COLOR_YELLOW, true) lzr_laser.TILE_LASER_C = maketile(lzr_globals.COLOR_CYAN, true) lzr_laser.TILE_LASER_M = maketile(lzr_globals.COLOR_MAGENTA, true) lzr_laser.TILE_LASER_W = maketile(lzr_globals.COLOR_WHITE, true) lzr_laser.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 -- Register laser nodes, i.e. the actual -- laser beams in the map. --[[ This registers a node for every possible laser combination. A laser node contains 1 to 3 laser beams, each along the X, Y and Z axis. Also, each laser beam can have one of each possible laser color (defined by colorcodes from 0 to lzr_globals.MAX_COLORCODE). When there is no laser on any axis, there is no need for a laser node. The number of registered nodes is ( ^ 3) - 1 ]] for color_x=0, lzr_globals.MAX_COLORCODE do for color_y=0, lzr_globals.MAX_COLORCODE do for color_z=0, lzr_globals.MAX_COLORCODE do local dirstring = color_x .. color_y .. color_z local dirs = lzr_laser.dirstring_to_dirs(dirstring) -- Count the active axes 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 color2tile = function(colorcode) if colorcode == 0 then return "blank.png" end if colorcode == lzr_globals.COLOR_RED then return lzr_laser.TILE_LASER_R elseif colorcode == lzr_globals.COLOR_GREEN then return lzr_laser.TILE_LASER_G elseif colorcode == lzr_globals.COLOR_YELLOW then return lzr_laser.TILE_LASER_Y elseif colorcode == lzr_globals.COLOR_BLUE then return lzr_laser.TILE_LASER_B elseif colorcode == lzr_globals.COLOR_CYAN then return lzr_laser.TILE_LASER_C elseif colorcode == lzr_globals.COLOR_MAGENTA then return lzr_laser.TILE_LASER_M elseif colorcode == lzr_globals.COLOR_WHITE then return lzr_laser.TILE_LASER_W else -- error return "no_texture.png" end end -- Pick a mesh depending on the axes on where to put -- a laser beam. -- The meshes are made so that the "ends" of the lasers -- are "open", i.e. don't have an additional face. -- This ensures the laser beam looks like a real -- continuous beam reather than a sequence of nodes. local tex, mesh -- Single laser if axes == 1 then -- Simple: Just pick a mesh for the laser direction, and then the color if axes_active.x then mesh = "lzr_laser_laser_100.obj" tex = { color2tile(color_x) } elseif axes_active.y then mesh = "lzr_laser_laser_010.obj" tex = { color2tile(color_y)} else mesh = "lzr_laser_laser_001.obj" tex = { color2tile(color_z) } end -- 2 lasers crossing elseif axes == 2 then -- A bit trickier: We have two primary colors from 2 lasers, -- but at the crossing, we mix both colors with the 'combined' var. if axes_active.x == false then mesh = "lzr_laser_laser_011.obj" -- Color mixing is just a bitwise OR of 2 colorcodes. Because the colorcodes -- are aligned in the correct way for this to work. local combined = bit.bor(color_y, color_z) tex = { color2tile(combined), color2tile(color_y), color2tile(color_z) } elseif axes_active.y == false then mesh = "lzr_laser_laser_101.obj" local combined = bit.bor(color_x, color_z) tex = { color2tile(color_x), color2tile(combined), color2tile(color_z) } else mesh = "lzr_laser_laser_110.obj" local combined = bit.bor(color_x, color_y) tex = { color2tile(color_x), color2tile(color_y), color2tile(combined) } end -- Note -- 3 lasers crossing elseif axes == 3 then -- Easy again: Pick a mesh and 3 colors for the 3 axes mesh = "lzr_laser_laser_111.obj" tex = { color2tile(color_x), color2tile(color_y), color2tile(color_z) } end -- This generates an unique number for each possible laser combination local lasergroup = lzr_laser.colors_to_laser_group(color_x, color_y, color_z) if tex then -- Finally register the laser minetest.register_node("lzr_laser:laser_"..dirstring, { description = S("Laser (@1)", lzr_laser.dirstring_to_colstring(dirstring)), paramtype = "light", light_source = lzr_globals.LASER_GLOW, drawtype = "mesh", mesh = mesh, sunlight_propagates = true, walkable = false, use_texture_alpha = lzr_laser.ALPHA_LASER, tiles = tex, pointable = false, buildable_to = true, groups = { laser = lasergroup, not_in_creative_inventory = 1, dig_immediate = 3 }, drop = "", }) end end end end