lazarr/mods/lzr_laser/blocks.lua

211 lines
5.4 KiB
Lua

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 },
})