-- LUALOCALS < ---------------------------------------------------------
local core, ipairs, nc, pairs, vector
    = core, ipairs, nc, pairs, vector
-- LUALOCALS > ---------------------------------------------------------

local modname = core.get_current_modname()

local active = {}

local function particles(item, player)
	local key = player:get_player_name() .. core.pos_to_string(item.pos, 1)
	.. core.pos_to_string(item.plane)
	local found = active[key]
	local now = core.get_us_time() / 1000000
	if found and found.exp > now then return end
	found = {
		exp = now + 2,
		id = core.add_particlespawner({
				amount = 5,
				time = 2,
				minpos = vector.add(item.pos,
					vector.multiply(item.plane, -0.5)),
				maxpos = vector.add(item.pos,
					vector.multiply(item.plane, 0.5)),
				minacc = vector.multiply(item.plane, -0.05),
				maxacc = vector.multiply(item.plane, 0.05),
				minsize = 0.2,
				maxsize = 0.5,
				minexptime = 1,
				maxexptime = 2,
				texture = modname .. "_port_output.png",
				playername = player.name
			})
	}
	active[key] = found
end

local function processcbb(item)
	for _, player in ipairs(core.get_connected_players()) do
		local pos = player:get_pos()
		local diff = pos and vector.subtract(pos, item.pos)
		if diff and vector.dot(diff, diff) < 64 then
			particles(item, player)
		end
	end
end

local get_node = core.get_node
nc.register_dnt({
		name = modname .. ":cbbs",
		time = 2,
		loop = true,
		ignore_stasis = true,
		autostart = true,
		nodenames = {"group:optic_source"},
		action = function(pos, node)
			local def = core.registered_nodes[node.name] or {}
			local src = def.optic_source
			if not src then return end
			src = src(pos, node)
			if not src then return end
			local cbbs = {}
			for _, dir in pairs(src) do
				nc.optic_scan(pos, dir, nil, get_node, cbbs)
			end
			for i = 1, #cbbs do processcbb(cbbs[i]) end
		end
	})
