local S = minetest.get_translator("lzr_laser") local mirror_out = { [0] = {1,0,0}, [1] = {0,0,-1}, [2] = {-1,0,0}, [3] = {0,0,1}, [4] = {1,0,0}, [5] = {0,1,0}, [6] = {-1,0,0}, [7] = {0,-1,0}, [8] = {1,0,0}, [9] = {0,-1,0}, [10] = {-1,0,0}, [11] = {0,1,0}, [12] = {0,-1,0}, [13] = {0,0,-1}, [14] = {0,1,0}, [15] = {0,0,1}, [16] = {0,1,0}, [17] = {0,0,-1}, [18] = {0,-1,0}, [19] = {0,0,1}, [20] = {-1,0,0}, [21] = {0,0,-1}, [22] = {1,0,0}, [23] = {0,0,1}, } lzr_laser.get_detector_dir = function(param2) local dir_input = minetest.facedir_to_dir(param2) if not dir_input then return end dir_input = vector.multiply(dir_input, -1) return dir_input end lzr_laser.check_detector = function(detector_pos, laser_dir) local detector = minetest.get_node(detector_pos) local detector_group = minetest.get_item_group(detector.name, "detector") if detector_group == 0 then return false end local reverse_laser_dir = vector.multiply(laser_dir, -1) local detector_dir_in = lzr_laser.get_detector_dir(detector.param2) if not detector_dir_in then return false end if vector.equals(reverse_laser_dir, detector_dir_in) then return true end return false end lzr_laser.get_mirror_dirs = function(param2) local dir_input = minetest.facedir_to_dir(param2) if not dir_input then return end dir_input = vector.multiply(dir_input, -1) local dir_output = vector.new(unpack(mirror_out[param2])) return dir_input, dir_output end -- Mirror a laser that touches a mirror at mirror_pos with a laser coming towards -- the mirror with the laser_dir direction (direction vector). -- Returns the "output direction" of the laser or false if can't get mirrored. lzr_laser.get_mirrored_laser_dir = function(mirror_pos, laser_dir) local mirror = minetest.get_node(mirror_pos) local mirror_group = minetest.get_item_group(mirror.name, "mirror") if mirror_group == 0 then return false end local reverse_laser_dir = vector.multiply(laser_dir, -1) local mirror_dir_in, mirror_dir_out = lzr_laser.get_mirror_dirs(mirror.param2) if not mirror_dir_in then return false end if vector.equals(reverse_laser_dir, mirror_dir_in) then return mirror_dir_out elseif vector.equals(reverse_laser_dir, mirror_dir_out) then return mirror_dir_in end return false end -- Update the whole playfield after placing or digging a laser node local full_update = function() lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END) end local after_rotate = function() full_update() end local register_element = function(subname, def) local def_core = table.copy(def) def_core.after_place_node = full_update def_core.after_dig_node = full_update def_core.after_rotate = after_rotate def_core.sounds = lzr_sounds.node_sound_wood_defaults() def_core._lzr_active = "lzr_laser:"..subname.."_on" def_core.tiles = def.tiles_off def_core.groups[subname] = 1 local def_on = table.copy(def_core) def_on._lzr_active = nil def_on._lzr_inactive = "lzr_laser:"..subname def_on.tiles = def.tiles_on def_on.drop = "lzr_laser:"..subname def_on.groups[subname] = 2 minetest.register_node("lzr_laser:"..subname, def_core) minetest.register_node("lzr_laser:"..subname.."_on", def_on) end register_element("mirror", { description = S("Mirror"), paramtype2 = "facedir", tiles_off = { "lzr_laser_mirror_top.png", "lzr_laser_mirror_top.png^[transformFY", "lzr_laser_mirror_hole.png", "lzr_laser_mirror_block.png", "lzr_laser_mirror_block.png", "lzr_laser_mirror_hole.png", }, tiles_on = { "lzr_laser_mirror_on_top.png", "lzr_laser_mirror_on_top.png^[transformFY", "lzr_laser_mirror_on_hole.png", "lzr_laser_mirror_on_block.png", "lzr_laser_mirror_on_block.png", "lzr_laser_mirror_on_hole.png", }, groups = { rotatable = 1, laser_block = 1, dig_immediate = 3 }, }) register_element("emitter", { description = S("Emitter"), paramtype2 = "facedir", tiles_off = { "lzr_laser_emitter.png", "lzr_laser_emitter.png", "lzr_laser_emitter.png", "lzr_laser_emitter.png", "lzr_laser_emitter.png", "lzr_laser_emitter_front.png", }, tiles_on = { "lzr_laser_emitter_on.png", "lzr_laser_emitter_on.png", "lzr_laser_emitter_on.png", "lzr_laser_emitter_on.png", "lzr_laser_emitter_on.png", "lzr_laser_emitter_on_front.png", }, on_rightclick = function(pos, node) local nname if node.name == "lzr_laser:emitter" then nname = "lzr_laser:emitter_on" else nname = "lzr_laser:emitter" end minetest.swap_node(pos, {name=nname, param2=node.param2}) lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END) end, on_punch = function(pos, node) local nname if node.name == "lzr_laser:emitter" then nname = "lzr_laser:emitter_on" else nname = "lzr_laser:emitter" end minetest.swap_node(pos, {name=nname, param2=node.param2}) lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END) end, groups = { laser_block = 1 }, }) register_element("detector", { description = S("Detector"), paramtype2 = "facedir", tiles_off = { "lzr_laser_detector.png", "lzr_laser_detector.png", "lzr_laser_detector.png", "lzr_laser_detector.png", "lzr_laser_detector.png", "lzr_laser_detector_front.png", }, tiles_on = { "lzr_laser_detector_on.png", "lzr_laser_detector_on.png", "lzr_laser_detector_on.png", "lzr_laser_detector_on.png", "lzr_laser_detector_on.png", "lzr_laser_detector_on_front.png", }, groups = { laser_block = 1 }, })