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()), после чего алгоритомм дейкстры построить путь и рендерить ток его?