Add support for laser mirroring

master
Wuzzy 2021-12-21 22:00:51 +01:00
parent 94e5945479
commit 46bac9d063
2 changed files with 49 additions and 6 deletions

View File

@ -43,6 +43,28 @@ lzr_laser.get_mirror_dirs = function(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
minetest.register_node("lzr_laser:mirror", {
description = S("Mirror"),
paramtype2 = "facedir",

View File

@ -10,7 +10,8 @@ function lzr_laser.add_laser(pos, dir)
local dirs = lzr_laser.vector_to_dirs(dir)
local dirstring = lzr_laser.dirs_to_dirstring(dirs)
minetest.set_node(pos, {name="lzr_laser:laser_"..dirstring})
return true
pos = vector.add(pos, dir)
return pos, dir
-- Laser through laser (laser intersection)
elseif minetest.get_item_group(node.name, "laser") > 0 then
local dirnum = minetest.get_item_group(node.name, "laser")
@ -21,7 +22,21 @@ function lzr_laser.add_laser(pos, dir)
local place_dirstring = lzr_laser.bitwise_or(dirstring_old, dirstring_new)
minetest.set_node(pos, {name="lzr_laser:laser_"..place_dirstring})
return true
pos = vector.add(pos, dir)
return pos, dir
-- Mirror laser
elseif minetest.get_item_group(node.name, "mirror") > 0 then
local mirror_dir = lzr_laser.get_mirrored_laser_dir(pos, dir)
if mirror_dir then
-- Activate mirror node
minetest.set_node(pos, {name="lzr_laser:mirror_on", param2 = node.param2})
-- Set new pos and dir
pos = vector.add(pos, mirror_dir)
dir = mirror_dir
return pos, dir
else
return false
end
-- Anything else: fail
else
return false
@ -52,23 +67,29 @@ function lzr_laser.travel_laser(pos, dir)
break
end
local i_node = minetest.get_node(i_pos)
cond = lzr_laser.add_laser(i_pos, dir)
i_pos = vector.add(i_pos, dir)
i_pos, dir = lzr_laser.add_laser(i_pos, dir)
if i_pos == false then
cond = false
end
end
end
-- Remove all lasers in area and disable all laser blocks
function lzr_laser.clear_lasers_in_area(pos1, pos2)
-- Remove lasers
local lasers = minetest.find_nodes_in_area(pos1, pos2, {"group:laser"})
minetest.bulk_set_node(lasers, {name="air"})
-- Disable laser blocks (mirror, etc.)
local laser_blocks = minetest.find_nodes_in_area(pos1, pos2, {"group:laser_block"})
for b=1, #laser_blocks do
local block = minetest.get_node(laser_blocks[b])
local block_pos = laser_blocks[b]
local block = minetest.get_node(block_pos)
local def = minetest.registered_nodes[block.name]
if def then
local inactive = def._lzr_inactive
if inactive then
minetest.set_node(block, {name="inactive", param2=block.param2})
minetest.set_node(block_pos, {name=inactive, param2=block.param2})
end
end
end