local cars, peds, link, linkl, navi = {}, {}, {}, {}, {}

-- Загрузка данных для каждого сегмента
for segmentID = 0, 63 do
    local segmentName = string.format("segment%d", segmentID)
    cars[segmentName] = require("nodes.cars." .. segmentName)
    peds[segmentName] = require("nodes.peds." .. segmentName)
    link[segmentName] = require("nodes.link." .. segmentName)
--    lnkl[segmentName] = require("nodes.lnkl." .. segmentName)
    navi[segmentName] = require("nodes.navi." .. segmentName)
end


-- Создаем шрифты
local Monocraft12Bold = renderCreateFont('Monocraft', 12, 1)
local Monocraft12Default = renderCreateFont('Monocraft', 12, 0)
local Monocraft8Default = renderCreateFont('Monocraft', 10, 0)
local screenResolutionX, screenResolutionY = getScreenResolution()

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while not isSampAvailable() do wait(0) end

    -- Регистрируем консольную команду "frf"
    sampfuncsRegisterConsoleCommand("frf", function(arg)
        sampAddChatMessage(arg, -1)
    end)

    renderSetRenderState(161, 1) -- Включаем мультимасштабное сглаживание (MSAA)

    -- Основной цикл
    while true do
        wait(0)
        local playerPosX, playerPosY = getCharCoordinates(PLAYER_PED)
        local tileID, tilePosX, tilePosY = getTileFromCoordinates(playerPosX, playerPosY)
        local segmentName = "segment" .. (tileID - 1)
        local segmentNodes, segmentLinks = cars[segmentName], link[segmentName]

        renderDebugText(playerPosX, playerPosY, tileID, tilePosX, tilePosY)
        renderNodesAndLinks(segmentNodes, segmentLinks, segmentName)
    end
end

-- Функция для отображения отладочного текста 
function renderDebugText(playerPosX, playerPosY, tileID, tilePosX, tilePosY)
    local debugText = string.format("XY: {FB7000}%d, %d {ffffff}area {FB7000}%d {ffffff}(%d, %d)", math.floor(playerPosX), math.floor(playerPosY), tileID, tilePosX, tilePosY)
    local debugTextShadow = string.format("XY: %d, %d area %d (%d, %d)", math.floor(playerPosX), math.floor(playerPosY), tileID, tilePosX, tilePosY)
    renderFontDrawText(Monocraft12Bold, debugTextShadow, 14, 876.5, 0xFF000000)
    renderFontDrawText(Monocraft12Default, debugText, 13, 875, 0xFFFFFFFF)
end

-- Функция для отображения узлов и связей
function renderNodesAndLinks(nodes, link, segmentName)
    local camPosX, camPosY, camPosZ = getActiveCameraCoordinates()
    
    for index, node in ipairs(nodes) do
        local nodePosX, nodePosY, nodePosZ = unpack(node)
        local linkID, linkedCount = node[4], getFirstFourBits(node[8])

        if isPointOnScreen(nodePosX, nodePosY, nodePosZ, 3) then
            if isLineOfSightClear(camPosX, camPosY, camPosZ, nodePosX, nodePosY, nodePosZ + 1.5, true, true, true, true, false) then
                renderNodeInfo(nodePosX, nodePosY, nodePosZ, camPosX, camPosY, camPosZ, index, linkID, linkedCount)
                renderLinkLines(nodePosX, nodePosY, nodePosZ, link, linkID, linkedCount)
            end
        end
    end
end

-- Функция для отображения информации о узле
function renderNodeInfo(nodePosX, nodePosY, nodePosZ, camPosX, camPosY, camPosZ, nodeID, linkID, linkedCount)
    local screenX, screenY = convert3DCoordsToScreen(nodePosX, nodePosY, nodePosZ)
    local distance = getDistanceBetweenCoords3d(nodePosX, nodePosY, nodePosZ, camPosX, camPosY, camPosZ)
    local boxSize = 50 / (1 + distance * 0.1)

    renderDrawBoxWithBorder(screenX, screenY, boxSize, boxSize, 0xFFFF0000, boxSize * 0.1, 0xFF000000)

    if distance < 100 then
        local font = Monocraft8Default
        local opacity = string.format("%x", (1 - (distance / 100)) * 255)
        local colorShadow, colorText = '0x' .. opacity .. '000000', '0x' .. opacity .. 'FFFFFF'
        local columnHeight = 12

        renderFontDrawText(font, 'nodeID: ' .. nodeID, screenX + 5, screenY + 2, tonumber(colorShadow))
        renderFontDrawText(font, 'nodeID: ' .. nodeID, screenX + 3, screenY, tonumber(colorText))
        renderFontDrawText(font, 'linkID: ' .. linkID, screenX + 5, screenY + columnHeight * 1, tonumber(colorShadow))
        renderFontDrawText(font, 'linkID: ' .. linkID, screenX + 3, screenY + columnHeight * 1, tonumber(colorText))
        renderFontDrawText(font, 'link: ' .. linkedCount, screenX + 5, screenY + columnHeight * 2, tonumber(colorShadow))
        renderFontDrawText(font, 'link: ' .. linkedCount, screenX + 3, screenY + columnHeight * 2, tonumber(colorText))
    end
end

-- Функция для отображения линий связей
function renderLinkLines(nodePosX, nodePosY, nodePosZ, link, linkID, linkedCount)
    local camPosX, camPosY, camPosZ = getActiveCameraCoordinates()
    
    for i = linkID, linkID + (linkedCount - 1) do
        local linkedID = link[i + 1][2] + 1
        local linkedSegmentID = link[i + 1][1] + 1
        local linkedNode = cars['segment' .. (linkedSegmentID - 1)][linkedID]
        local linkedPosX, linkedPosY, linkedPosZ = unpack(linkedNode)

        if isPointOnScreen(linkedPosX, linkedPosY, linkedPosZ, 0) then
            if isLineOfSightClear(camPosX, camPosY, camPosZ, linkedPosX, linkedPosY, linkedPosZ + 1.5, true, true, true, true, false) then
                local screenX, screenY = convert3DCoordsToScreen(nodePosX, nodePosY, nodePosZ)
                local linkedScreenX, linkedScreenY = convert3DCoordsToScreen(linkedPosX, linkedPosY, linkedPosZ)
                local lineColors = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF, 0xFFFFFF00}
                renderDrawLine(screenX, screenY, linkedScreenX, linkedScreenY, 1, lineColors[(i % #lineColors) + 1])
            end
        end
    end
end

-- Функция для получения ID тайла из координат
function getTileFromCoordinates(x, y)
    local TILE_SIZE, MAP_OFFSET = 6000 / 8, 3000
    local tileX = math.floor((x + MAP_OFFSET) / TILE_SIZE) + 1
    local tileY = math.floor((y + MAP_OFFSET) / TILE_SIZE) + 1
    return (tileY - 1) * 8 + tileX, tileX, tileY
end

-- Функция для получения первых четырех битов
function getFirstFourBits(num)
    return num % 16
end


как из этого можно написать код который будет находить ближайшую к персонажу ноду(positionX, positionY, positionZ = getCharCoordinates(playerPed)) и ближайшую к (	result, posX, posY, posZ = getTargetBlipCoordinates()), после чего алгоритомм дейкстры построить путь?