local S = minetest.get_translator("lzr_laser")

local TEX_LASER
local ALPHA_LASER
if lzr_globals.OPAQUE_LASERS then
	TEX_LASER = "lzr_laser_laser_opaque.png"
	ALPHA_LASER = "clip"
else
	TEX_LASER = "lzr_laser_laser.png"
	ALPHA_LASER = "blend"
end

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_front_dir = function(param2)
	if not param2 then
		return
	end
	local dir_input = minetest.facedir_to_dir(param2)
	if not dir_input then
		return
	end
	local v = vector.new(dir_input[1], dir_input[2], dir_input[3])
	dir_input = vector.multiply(v, -1)
	return dir_input
end

lzr_laser.check_front = function(node_pos, laser_dir)
	local node = minetest.get_node(node_pos)
	local node_dir_in = lzr_laser.get_front_dir(node.param2)
	if not node_dir_in then
		return false
	end
	local reverse_laser_dir = vector.multiply(laser_dir, -1)
	if vector.equals(reverse_laser_dir, node_dir_in) then
		return true
	end
	return false
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
	return lzr_laser.check_front(detector_pos, laser_dir)
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 <output direction>, <mirror output side>
-- 	1) If the laser can be mirrored, then <output direction> is the direction of
-- 	the mirrored laser and <mirror output> denotes on of the 2 possible
-- 	sides the laser came from: true if it came in the front side, false if
-- 	it came from the angled side. <mirror output> is useful for the
-- 	transmissive mirror.
-- 	2) If the laser cannot be mirrored <mirror output> is false and
-- 	<mirror output side> is nil
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")
	local mirror_transmissive_group = minetest.get_item_group(mirror.name, "transmissive_mirror")
	if mirror_group == 0 and mirror_transmissive_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, true
	elseif vector.equals(reverse_laser_dir, mirror_dir_out) then
		return mirror_dir_in, false
	end
	return false
end

function lzr_laser.unlock_chests(min, max)
	local closed_chests = minetest.find_nodes_in_area(min, max, {"group:chest_closed"})
	local detectors = minetest.find_nodes_in_area(min, max, {"group:detector"})
	for c=1, #closed_chests do
		local cpos = closed_chests[c]
		local node = minetest.get_node(cpos)
		local def = minetest.registered_nodes[node.name]
		if def._lzr_unlock then
			def._lzr_unlock(cpos, node)
			for d=1, #detectors do
				local dpos = detectors[d]
				lzr_laser.particle_line(dpos, cpos, "lzr_laser_particle_trigger.png")
			end
		end
	end
end

-- Update the whole playfield after placing or digging a laser node
local full_update = function()
	local state = lzr_gamestate.get_state()
	if state ~= lzr_gamestate.LEVEL and state ~= lzr_gamestate.EDITOR then
		return
	end
	lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
	if state == lzr_gamestate.EDITOR then
		return
	end
	local done = lzr_laser.check_level_won()
	if done then
		lzr_levels.level_complete()
	else
		local detectors = lzr_laser.check_all_detectors()
		if detectors then
			lzr_laser.unlock_chests(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
		end
	end
end

-- Same as above, but special case after a detector was placed.
-- This is hack to tell the detector check that there one detector in the player
-- inventory has to be ignored because after_dig_node is called BEFORE
-- the inventory change after placing the node.
local full_update_detector_placed = function()
	local state = lzr_gamestate.get_state()
	if state ~= lzr_gamestate.LEVEL and state ~= lzr_gamestate.EDITOR then
		return
	end
	lzr_laser.full_laser_update(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
	if state == lzr_gamestate.EDITOR then
		return
	end
	local done = lzr_laser.check_level_won()
	if done then
		lzr_levels.level_complete()
	else
		local detectors = lzr_laser.check_all_detectors(true)
		if detectors then
			lzr_laser.unlock_chests(lzr_globals.PLAYFIELD_START, lzr_globals.PLAYFIELD_END)
		end
	end
end

local after_rotate = function()
	full_update()
end

local element_can_dig = function()
	return lzr_gamestate.get_state() ~= lzr_gamestate.LEVEL_COMPLETE
end
local element_on_place = function(itemstack, placer, pointed_thing)
	if lzr_gamestate.get_state() == lzr_gamestate.LEVEL_COMPLETE then
		-- Prevent node placement when in 'level complete' state
		return itemstack
	else
		-- node's on_rightclick action takes precedence
		if pointed_thing.type == "node" and placer then
			local node = minetest.get_node(pointed_thing.under)
			local def = minetest.registered_nodes[node.name]
			local sneak = placer:get_player_control().sneak
			if def and def.on_rightclick and not sneak then
				def.on_rightclick(pointed_thing.under, node, placer, itemstack, pointed_thing)
				return itemstack
			end
		end
		-- Default node placement behavior
		return minetest.item_place_node(itemstack, placer, pointed_thing)
	end
end

local register_element = function(subname, def, options)
	local def_core = table.copy(def)
	if not options then options = {} end
	if options.is_detector then
		def_core.after_place_node = full_update_detector_placed
	else
		def_core.after_place_node = full_update
	end
	if options.not_walkable_if_off then
		def_core.walkable = false
	end
	if options.allow_take then
		def_core._lzr_takable = "lzr_laser:"..subname.."_takable"
	end

	def_core.description = S("@1 (fixed)", def.description)
	def_core.after_dig_node = full_update
	def_core._after_rotate = after_rotate
	if options.activate ~= false then
		def_core._lzr_active = "lzr_laser:"..subname.."_on"
	end
	def_core.tiles = def.tiles_off
	def_core.mesh = def.mesh_off
	if not def_core.groups then
		def_core.groups = {}
	end
	def_core.groups.breakable = 1
	local groupname
	if options.group then
		groupname = options.group
	else
		groupname = subname
	end
	def_core.groups[groupname] = 1
	def_core.can_dig = element_can_dig
	def_core.on_place = element_on_place
	if options.inactive ~= nil then
		def_core._lzr_inactive = options.inactive
		if not options.keep_state_on_take then
			def_core.drop = options.inactive
		end
	end

	minetest.register_node("lzr_laser:"..subname, def_core)

	local def_core_on
	if options.activate ~= false then
		def_core_on = table.copy(def_core)
		if options.not_walkable_if_off then
			def_core_on.walkable = true
		elseif options.not_walkable_if_on then
			def_core_on.walkable = false
		end
		def_core_on.description = S("@1 (fixed, active)", def.description)
		def_core_on._lzr_active = nil
		def_core_on._lzr_inactive = "lzr_laser:"..subname
		def_core_on.tiles = def.tiles_on
		def_core_on.mesh = def.mesh_on
		if not options.keep_state_on_take then
			def_core_on.drop = "lzr_laser:"..subname
		end
		if options.allow_take then
			def_core_on._lzr_takable = "lzr_laser:"..subname.."_takable_on"
		end
		def_core_on.groups[groupname] = 2
		def_core_on.light_source = def.light_source_on
		minetest.register_node("lzr_laser:"..subname.."_on", def_core_on)
	end

	if options.allow_take then
		local def_takable = table.copy(def_core)
		def_takable.tiles = def.tiles_takable_off
		def_takable.groups.takable = 1
		def_takable._lzr_untakable = "lzr_laser:"..subname
		def_takable.description = def.description
		if options.inactive ~= nil then
			def_takable._lzr_inactive = options.inactive.."_takable"
			if not options.keep_state_on_take then
				def_takable.drop = options.inactive.."_takable"
			end
		end

		minetest.register_node("lzr_laser:"..subname.."_takable", def_takable)

		if options.activate ~= false then
			def_takable._lzr_active = "lzr_laser:"..subname.."_takable_on"
			local def_takable_on = table.copy(def_core_on)
			def_takable_on._lzr_untakable = "lzr_laser:"..subname.."_on"
			def_takable_on.tiles = def.tiles_takable_on
			def_takable_on.light_source = def.light_source_on
			def_takable_on.groups.takable = 1
			def_takable_on.description = S("@1 (active)", def.description)
			if not options.keep_state_on_take then
				def_takable_on.drop = "lzr_laser:"..subname.."_takable"
			end
			def_takable_on._lzr_inactive = "lzr_laser:"..subname.."_takable"
			minetest.register_node("lzr_laser:"..subname.."_takable_on", def_takable_on)
		end
	end
end

register_element("crate", {
	description = S("Crate"),
	tiles_off = {
		"lzr_laser_crate_fixed.png",
	},
	tiles_takable_off = {
		"lzr_laser_crate.png",
	},
	sounds = lzr_sounds.node_sound_wood_defaults(),
}, { allow_take = true, activate = false })

register_element("mirror", {
	description = S("Mirror"),
	paramtype = "light",
	paramtype2 = "facedir",
	tiles_off = {
		{name="lzr_laser_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
		{name="lzr_laser_mirror_mirror.png", backface_culling=true},
		{name="lzr_laser_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
	},
	tiles_on = {
		{name=TEX_LASER, backface_culling=true},
		{name="lzr_laser_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
		{name="lzr_laser_mirror_mirror.png", backface_culling=true},
		{name="lzr_laser_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
	},
	tiles_takable_off = {
		{name="lzr_laser_mirror_block.png", backface_culling=true},
		{name="lzr_laser_mirror_mirror.png", backface_culling=true},
		{name="lzr_laser_mirror_block.png", backface_culling=true},
	},
	tiles_takable_on = {
		{name=TEX_LASER, backface_culling=true},
		{name="lzr_laser_mirror_block.png", backface_culling=true},
		{name="lzr_laser_mirror_mirror.png", backface_culling=true},
		{name="lzr_laser_mirror_block.png", backface_culling=true},
	},
	use_texture_alpha = ALPHA_LASER,
	drawtype = "mesh",
	mesh_off = "lzr_laser_mirror.obj",
	mesh_on = "lzr_laser_mirror_on.obj",

	light_source_on = lzr_globals.LASER_GLOW,

	groups = { rotatable = 1, laser_block = 1 },
	sounds = lzr_sounds.node_sound_glass_defaults({
		_rotate = {name = "lzr_laser_mirror_rotate", gain = 1.0},
	})
}, { allow_take = true })

local tm_def = {
	description = S("Transmissive Mirror"),
	paramtype = "light",
	paramtype2 = "facedir",
	use_texture_alpha = ALPHA_LASER,
	drawtype = "mesh",
	groups = { rotatable = 1, laser_block = 1 },
	sounds = lzr_sounds.node_sound_glass_defaults({
		_rotate = {name = "lzr_laser_mirror_rotate", gain = 1.0},
	}),
	_lzr_transmissive_mirror_00 = "lzr_laser:transmissive_mirror_00",
	_lzr_transmissive_mirror_01 = "lzr_laser:transmissive_mirror_01",
	_lzr_transmissive_mirror_10 = "lzr_laser:transmissive_mirror_10",
	_lzr_transmissive_mirror_11 = "lzr_laser:transmissive_mirror_11",
}

local tm_def_off = table.copy(tm_def)
tm_def_off._lzr_transmissive_mirror_state = "00"
tm_def_off.tiles_off = {
	{name="lzr_laser_transmissive_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror_out.png", backface_culling=true},
}
tm_def_off.tiles_takable_off = {
	{name="lzr_laser_transmissive_mirror_block.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror_out.png", backface_culling=true},
}
tm_def_off.mesh_off = "lzr_laser_mirror.obj"
-- Use custom fields to identify transmissive mirror states


-- Transmissive Mirror
local tm_def_on_01 = table.copy(tm_def)
tm_def_on_01.light_source = lzr_globals.LASER_GLOW
tm_def_on_01._lzr_transmissive_mirror_state = "01"
tm_def_on_01.description = S("Transmissive Mirror (active, 01)")
tm_def_on_01.tiles_off = {
	{name=TEX_LASER, backface_culling=true},
	{name="lzr_laser_transmissive_mirror_block.png^lzr_laser_fixed.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror_out.png", backface_culling=true},
}
tm_def_on_01.tiles_takable_off = {
	{name=TEX_LASER, backface_culling=true},
	{name="lzr_laser_transmissive_mirror_block.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror.png", backface_culling=true},
	{name="lzr_laser_transmissive_mirror_mirror_out.png", backface_culling=true},
}
tm_def_on_01.mesh_off = "lzr_laser_mirror_on_thru1.obj"

local tm_def_on_10 = table.copy(tm_def_on_01)
tm_def_on_10._lzr_transmissive_mirror_state = "10"
tm_def_on_10.description = S("Transmissive Mirror (active, 10)")
tm_def_on_10.mesh_off = "lzr_laser_mirror_on_thru2.obj"

local tm_def_on_11 = table.copy(tm_def_on_01)
tm_def_on_11._lzr_transmissive_mirror_state = "11"
tm_def_on_11.description = S("Transmissive Mirror (active, 11)")
tm_def_on_11.mesh_off = "lzr_laser_mirror_on_thru3.obj"

local tm_options_off = { allow_take = true, activate = false, group = "transmissive_mirror" }
local tm_options_on = { allow_take = true, activate = false, group = "transmissive_mirror", inactive = "lzr_laser:transmissive_mirror_00" }
register_element("transmissive_mirror_00", tm_def_off, tm_options_off)
register_element("transmissive_mirror_01", tm_def_on_01, tm_options_on)
register_element("transmissive_mirror_10", tm_def_on_10, tm_options_on)
register_element("transmissive_mirror_11", tm_def_on_11, tm_options_on)

register_element("crystal", {
	description = S("Crystal"),
	paramtype = "light",
	paramtype2 = "facedir",
	tiles_takable_off = {
		"lzr_laser_crystal.png",
	},
	tiles_takable_on = {
		"lzr_laser_crystal_on.png",
	},
	tiles_off = {
		"lzr_laser_crystal.png^lzr_laser_fixed.png",
	},
	tiles_on = {
		"lzr_laser_crystal_on.png^lzr_laser_fixed.png",
	},
	light_source_on = lzr_globals.LASER_GLOW,
	groups = { laser_block = 1 },
	sounds = lzr_sounds.node_sound_glass_defaults({
		_rotate = {name = "lzr_laser_mirror_rotate", gain = 1.0},
	})
}, { allow_take = true })




register_element("emitter", {
	description = S("Emitter"),
	paramtype2 = "facedir",
	tiles_takable_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_takable_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",

	},
	tiles_off = {
		"lzr_laser_emitter.png^lzr_laser_fixed.png",
		"lzr_laser_emitter.png^lzr_laser_fixed.png",
		"lzr_laser_emitter.png^lzr_laser_fixed.png",
		"lzr_laser_emitter.png^lzr_laser_fixed.png",
		"lzr_laser_emitter.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_front.png^lzr_laser_fixed.png",
	},
	tiles_on = {
		"lzr_laser_emitter_on.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_on.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_on.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_on.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_on.png^lzr_laser_fixed.png",
		"lzr_laser_emitter_on_front.png^lzr_laser_fixed.png",

	},
	light_source_on = 7,
	_lzr_on_toggle = function(pos, node)
		if lzr_gamestate.get_state() == lzr_gamestate.LEVEL_COMPLETE then
			return
		end
		local nname
		local on = false
		if node.name == "lzr_laser:emitter" then
			nname = "lzr_laser:emitter_on"
			on = true
		elseif node.name == "lzr_laser:emitter_on" then
			nname = "lzr_laser:emitter"
		elseif node.name == "lzr_laser:emitter_takable" then
			nname = "lzr_laser:emitter_takable_on"
			on = true
		elseif node.name == "lzr_laser:emitter_takable_on" then
			nname = "lzr_laser:emitter_takable"
		end
		if on then
			minetest.sound_play({name="lzr_laser_emitter_activate", gain=1.0}, {pos=pos}, true)
		else
			minetest.sound_play({name="lzr_laser_emitter_activate", gain=0.8}, {pos=pos, pitch=0.7}, true)
		end
		minetest.swap_node(pos, {name=nname, param2=node.param2})
		full_update()
	end,
	groups = { rotatable = 2, laser_block = 1 },
	sounds = lzr_sounds.node_sound_wood_defaults(),
}, { allow_take = true, keep_state_on_take = true })

register_element("detector", {
	description = S("Detector"),
	paramtype2 = "facedir",
	tiles_off = {
		"lzr_laser_detector.png^lzr_laser_fixed.png",
		"lzr_laser_detector.png^lzr_laser_fixed.png",
		"lzr_laser_detector.png^lzr_laser_fixed.png",
		"lzr_laser_detector.png^lzr_laser_fixed.png",
		"lzr_laser_detector.png^lzr_laser_fixed.png",
		"lzr_laser_detector_front.png^lzr_laser_fixed.png",
	},
	tiles_on = {
		"lzr_laser_detector_on.png^lzr_laser_fixed.png",
		"lzr_laser_detector_on.png^lzr_laser_fixed.png",
		"lzr_laser_detector_on.png^lzr_laser_fixed.png",
		"lzr_laser_detector_on.png^lzr_laser_fixed.png",
		"lzr_laser_detector_on.png^lzr_laser_fixed.png",
		"lzr_laser_detector_on_front.png^lzr_laser_fixed.png",
	},
	tiles_takable_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_takable_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",
	},
	light_source_on = 5,
	groups = { rotatable = 2, laser_block = 1 },
	sounds = lzr_sounds.node_sound_wood_defaults(),
}, { allow_take = true, is_detector = true })

-- Is non-walkable if off,
-- and walkable if on.
register_element("skull_cursed", {
	description = S("Cursed Skull (experimental)"),
	paramtype2 = "facedir",
	-- TODO: Draw proper images
	tiles_off = {
		"lzr_laser_cskull_top.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_bottom.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_side.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_side.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_back.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_front.png^lzr_laser_fixed.png",
	},
	tiles_on = {
		"lzr_laser_cskull_on_top.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_on_bottom.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_on_side.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_on_side.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_on_back.png^lzr_laser_fixed.png",
		"lzr_laser_cskull_on_front.png^lzr_laser_fixed.png",
	},
	tiles_takable_off = {
		"lzr_laser_cskull_top.png",
		"lzr_laser_cskull_bottom.png",
		"lzr_laser_cskull_side.png",
		"lzr_laser_cskull_side.png",
		"lzr_laser_cskull_back.png",
		"lzr_laser_cskull_front.png",
	},
	tiles_takable_on = {
		"lzr_laser_cskull_on_top.png",
		"lzr_laser_cskull_on_bottom.png",
		"lzr_laser_cskull_on_side.png",
		"lzr_laser_cskull_on_side.png",
		"lzr_laser_cskull_on_back.png",
		"lzr_laser_cskull_on_front.png",
	},
	light_source_on = 5,
	groups = { rotatable = 2, laser_block = 1 },
	on_rotate = screwdriver.rotate_simple,
	sounds = lzr_sounds.node_sound_stone_defaults(),
}, { allow_take = true, not_walkable_if_off = true })

-- Is walkable if off,
-- and non-walkable if on.
register_element("skull_shy", {
	description = S("Shy Skull (experimental)"),
	paramtype2 = "facedir",
	-- TODO: Draw proper images
	tiles_off = {
		"lzr_laser_sskull_top.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_bottom.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_side.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_side.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_back.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_front.png^lzr_laser_fixed.png",
	},
	tiles_on = {
		"lzr_laser_sskull_on_top.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_on_bottom.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_on_side.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_on_side.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_on_back.png^lzr_laser_fixed.png",
		"lzr_laser_sskull_on_front.png^lzr_laser_fixed.png",
	},
	tiles_takable_off = {
		"lzr_laser_sskull_top.png",
		"lzr_laser_sskull_bottom.png",
		"lzr_laser_sskull_side.png",
		"lzr_laser_sskull_side.png",
		"lzr_laser_sskull_back.png",
		"lzr_laser_sskull_front.png",
	},
	tiles_takable_on = {
		"lzr_laser_sskull_on_top.png",
		"lzr_laser_sskull_on_bottom.png",
		"lzr_laser_sskull_on_side.png",
		"lzr_laser_sskull_on_side.png",
		"lzr_laser_sskull_on_back.png",
		"lzr_laser_sskull_on_front.png",
	},
	light_source_on = 5,
	groups = { rotatable = 2, laser_block = 1 },
	on_rotate = screwdriver.rotate_simple,
	sounds = lzr_sounds.node_sound_stone_defaults(),
}, { allow_take = true, not_walkable_if_on = true })

minetest.register_node("lzr_laser:barricade", {
	description = S("Barricade"),
	drawtype = "mesh",
	mesh = "lzr_laser_burning.obj",
	paramtype = "light",
	inventory_image = "xdecor_baricade.png",
	wield_image = "xdecor_baricade.png",
	tiles = {"blank.png","xdecor_baricade.png"},
	use_texture_alpha = "clip",
	groups = { breakable = 1, flammable = 1, laser_destroys = 2 },
	sounds = lzr_sounds.node_sound_wood_defaults({
		dug = {name="lzr_laser_barricade_break", gain=1.0},
	}),
	on_place = element_on_place,
	can_dig = element_can_dig,
	_lzr_active = "lzr_laser:barricade_on",
})

minetest.register_node("lzr_laser:barricade_on", {
	description = S("Burning Barricade"),
	drawtype = "mesh",
	paramtype = "light",
	light_source = 12,
	mesh = "lzr_laser_burning.obj",
	inventory_image = "lzr_laser_baricade_burning.png",
	wield_image = "lzr_laser_baricade_burning.png",
	use_texture_alpha = "clip",
	tiles = {
		{ name="fire_basic_flame_animated.png", animation={
			type = "vertical_frames",
			aspect_w = 16,
			aspect_h = 16,
			length = 1.0,
		},},
		{ name="lzr_laser_baricade_burning_animated.png", animation={
			type = "vertical_frames",
			aspect_w = 16,
			aspect_h = 16,
			length = 1.0,
		},},
	},
	groups = { breakable = 1, not_in_creative_inventory = 1 },
	sounds = lzr_sounds.node_sound_wood_defaults({
		dug = {name="lzr_laser_barricade_break", gain=1.0},
	}),
	on_construct = function(pos)
		minetest.sound_play({name="lzr_laser_quickburn", gain=1.0}, {pos=pos}, true)
		local timer = minetest.get_node_timer(pos)
		timer:start(1)
	end,
	on_timer = function(pos)
		-- spawn a few particles for the removed node
		minetest.add_particlespawner({
			amount = 16,
			time = 0.001,
			minpos = vector.subtract(pos, vector.new(0.5, 0.5, 0.5)),
			maxpos = vector.add(pos, vector.new(0.5, 0.5, 0.5)),
			minvel = vector.new(-0.5, -0.2, -0.5),
			maxvel = vector.new(0.5, 0.2, 0.5),
			minacc = vector.new(0, -lzr_globals.GRAVITY, 0),
			maxacc = vector.new(0, -lzr_globals.GRAVITY, 0),
			minsize = 1.5,
			maxsize = 1.5,
			node = {name="lzr_laser:barricade"},
		})
		-- Play randomly-pitched break sound
		local pitch = 1.0+math.random(-100, 100)*0.001 -- 0.9..1.1
		minetest.sound_play({name="lzr_laser_barricade_break", gain=1.0}, {gain=1.0, pitch=pitch, pos=pos}, true)
		-- remove node
		minetest.remove_node(pos)
		full_update()

		-- propagate to neighbors
		local posses = {
			vector.new(-1,0,0),
			vector.new(1,0,0),
			vector.new(0,-1,0),
			vector.new(0,1,0),
			vector.new(0,0,-1),
			vector.new(0,0,1),
		}
		for p=1, #posses do
			local ppos = vector.add(pos, posses[p])
			local node = minetest.get_node(ppos)
			local def = minetest.registered_nodes[node.name]
			if def and def._lzr_active then
				if minetest.get_item_group(node.name, "flammable") > 0 then
					minetest.set_node(ppos, {name=def._lzr_active})
				end
			end
		end
	end,
	drop = "",
	on_place = element_on_place,
	can_dig = element_can_dig,
	_lzr_inactive = "lzr_laser:barricade",
})


