Привет ГПТ!
Помоги зафиксить код:
-- Клиентский скрипт для отображения радиального меню взаимодействия
include("autorun/sh_interactions_config.lua")

local interactionRadius = 100 -- Радиус для выбора игроков
local interactionFOV = 30 -- Поле зрения для отображения G-кнопки
local isShowingMenu = false
local targetPlayer = nil
local consentMenu = nil

-- Функция для создания радиального меню с использованием аддона
local function CreateRadialMenu()
    -- Создаем объект меню с использованием аддона
    local menu = mvp.meta.radialMenu:New()
    return menu
end

-- Функция для создания окна запроса согласия
local function CreateConsentRequestMenu(requester, action)
    if IsValid(consentMenu) then
        consentMenu:Close()
    end

    consentMenu = CreateRadialMenu()

    consentMenu:AddOption("Согласен", "Согласие на действие: " .. action, Material("path/to/accept_icon.png"), Color(0, 255, 0), function()
        net.Start("ConsentResponse")
        net.WriteString(action)
        net.WriteEntity(requester)
        net.WriteBool(true)
        net.SendToServer()
        consentMenu:Close()
        consentMenu = nil
    end)

    consentMenu:AddOption("Отклонить", "Отказ от действия: " .. action, Material("path/to/decline_icon.png"), Color(255, 0, 0), function()
        net.Start("ConsentResponse")
        net.WriteString(action)
        net.WriteEntity(requester)
        net.WriteBool(false)
        net.SendToServer()
        consentMenu:Close()
        consentMenu = nil
    end)

    -- Открытие меню
    consentMenu:Open()
end

-- Обработка сетевого запроса на согласие
net.Receive("ConsentRequest", function()
    local requester = net.ReadEntity()
    local action = net.ReadString()
    CreateConsentRequestMenu(requester, action)
end)

-- Функция для создания меню с действиями из категории
local function OpenCategoryMenu(categoryActions, target)
    local menu = CreateRadialMenu() -- Создаем меню

    for name, action in pairs(categoryActions) do
        menu:AddOption(action.displayName, "Выполнить действие", Material("path/to/icon.png"), Color(150, 150, 255), function()
            net.Start("RequestInteraction")
            net.WriteString(name)
            net.WriteEntity(target)
            net.SendToServer()

            -- Закрываем меню после выбора действия
            menu:Close()
            isShowingMenu = false
            targetPlayer = nil
        end)
    end

    -- Открытие меню
    menu:Open()
end

-- Функция для отображения главного радиального меню с категориями
local function OpenMainRadialMenu(target)
    local menu = CreateRadialMenu() -- Создаем новое меню через аддон

    -- Добавляем категории в меню
    menu:AddOption("Другие действия", "Выберите из списка других действий", Material("path/to/icon.png"), Color(255, 150, 150), function()
        OpenCategoryMenu(InteractionsConfig.OtherActions, target)
        menu:Close() -- Закрываем главное меню после открытия подменю
    end)

    menu:AddOption("Дружелюбные действия", "Выберите дружелюбные действия", Material("path/to/icon.png"), Color(150, 255, 150), function()
        OpenCategoryMenu(InteractionsConfig.FriendlyActions, target)
        menu:Close()
    end)

    menu:AddOption("Медицинские действия", "Выберите медицинские действия", Material("path/to/icon.png"), Color(150, 255, 150), function()
        OpenCategoryMenu(InteractionsConfig.MedicalActions, target)
        menu:Close()
    end)

    menu:AddOption("Недружелюбные действия", "Выберите недружелюбные действия", Material("path/to/icon.png"), Color(255, 150, 150), function()
        OpenCategoryMenu(InteractionsConfig.SexActions, target)
        menu:Close()
    end)

    -- Открытие меню
    menu:Open()
end

-- Вызов вложенного меню
local function OpenNestedCategoryMenu(target)
    local menu = CreateRadialMenu()

    local subMenuHolder = menu:AddOption("Вложенное меню", "Описание", Material("path/to/icon.png"), Color(255, 200, 200))

    -- Добавляем опции во вложенное меню
    subMenuHolder:AddSubOption("Опция 1", "Описание 1", Material("path/to/icon1.png"), Color(200, 255, 150), function() print("Опция 1 выбрана") end)
    subMenuHolder:AddSubOption("Опция 2", "Описание 2", Material("path/to/icon2.png"), Color(150, 255, 200), function() print("Опция 2 выбрана") end)

    -- Открываем главное меню
    menu:Open()
end

-- Функция для рисования кнопки "G" над игроками
local function DrawGButton(player)
    local pos = player:LocalToWorld(player:OBBCenter()):ToScreen()
    draw.SimpleText("G", "Trebuchet24", pos.x, pos.y, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end

-- Проверка, находится ли игрок в поле зрения
local function IsPlayerInFOV(ply)
    local localPlayer = LocalPlayer()
    local forward = localPlayer:EyeAngles():Forward()
    local direction = (ply:GetPos() - localPlayer:GetPos()):GetNormalized()
    local dot = forward:Dot(direction)

    local angle = math.deg(math.acos(dot))
    return angle <= (interactionFOV / 2)
end

-- Функция для проверки попадания трассировки на игрока
local function TraceForPlayer()
    local localPlayer = LocalPlayer()
    local trace = util.TraceLine({
        start = localPlayer:EyePos(),
        endpos = localPlayer:EyePos() + localPlayer:GetAimVector() * interactionRadius,
        filter = localPlayer
    })

    if trace.Hit and IsValid(trace.Entity) and trace.Entity:IsPlayer() then
        return trace.Entity
    end

    return nil
end

-- Хук для рисования кнопки "G" на HUD
hook.Add("HUDPaint", "ShowGKeyOnClosePlayers", function()
    if isShowingMenu then return end -- Проверяем, не открыто ли уже меню

    local localPlayer = LocalPlayer()

    local tracedPlayer = TraceForPlayer()

    if IsValid(tracedPlayer) and tracedPlayer:Alive() and IsPlayerInFOV(tracedPlayer) then
        DrawGButton(tracedPlayer) -- Рисуем кнопку "G"
        targetPlayer = tracedPlayer -- Устанавливаем игрока как цель
    else
        targetPlayer = nil -- Сбрасываем цель, если игрок не найден
    end
end)

-- Хук для проверки нажатия кнопки "G"
hook.Add("Think", "CheckGKeyPress", function()
    local localPlayer = LocalPlayer()

    -- Проверка, что фокус не находится на элементе ввода текста и игра не в паузе
    if not vgui.GetKeyboardFocus() and not gui.IsGameUIVisible() and input.IsKeyDown(KEY_G) and targetPlayer then
        if not isShowingMenu then -- Проверяем, не открыто ли уже меню
            isShowingMenu = true
            OpenMainRadialMenu(targetPlayer) -- Открываем главное меню
        end
    end

    -- Обновляем состояние меню и игрока, если меню закрыто
    if isShowingMenu and targetPlayer then
        local distance = localPlayer:GetPos():Distance(targetPlayer:GetPos())
        if distance > interactionRadius then
            isShowingMenu = false
            targetPlayer = nil
        end
    end
end)

-- Функция для закрытия меню
local function CloseRadialMenu(frame)
    if IsValid(frame) then
        frame:Close()
    end
    isShowingMenu = false
    targetPlayer = nil
end

-- Функция для рисования круга
function draw.Circle(x, y, radius, seg)
    local cir = {}
    table.insert(cir, {x = x, y = y})

    for i = 0, seg do
        local a = math.rad((i / seg) * -360)
        table.insert(cir, {x = x + math.sin(a) * radius, y = y + math.cos(a) * radius})
    end

    surface.DrawPoly(cir)
end

-- Уведомление о завершении клиентской загрузки
print("Client-side Interaction Menu loaded.")-- Клиентский скрипт для отображения радиального меню взаимодействия
include("autorun/sh_interactions_config.lua")

local interactionRadius = 100 -- Радиус для выбора игроков
local interactionFOV = 30 -- Поле зрения для отображения G-кнопки
local isShowingMenu = false
local targetPlayer = nil
local consentMenu = nil

-- Функция для создания радиального меню с использованием аддона
local function CreateRadialMenu()
    -- Создаем объект меню с использованием аддона
    local menu = mvp.meta.radialMenu:New()
    return menu
end

-- Функция для создания окна запроса согласия
local function CreateConsentRequestMenu(requester, action)
    if IsValid(consentMenu) then
        consentMenu:Close()
    end

    consentMenu = CreateRadialMenu()

    consentMenu:AddOption("Согласен", "Согласие на действие: " .. action, Material("path/to/accept_icon.png"), Color(0, 255, 0), function()
        net.Start("ConsentResponse")
        net.WriteString(action)
        net.WriteEntity(requester)
        net.WriteBool(true)
        net.SendToServer()
        consentMenu:Close()
        consentMenu = nil
    end)

    consentMenu:AddOption("Отклонить", "Отказ от действия: " .. action, Material("path/to/decline_icon.png"), Color(255, 0, 0), function()
        net.Start("ConsentResponse")
        net.WriteString(action)
        net.WriteEntity(requester)
        net.WriteBool(false)
        net.SendToServer()
        consentMenu:Close()
        consentMenu = nil
    end)

    -- Открытие меню
    consentMenu:Open()
end

-- Обработка сетевого запроса на согласие
net.Receive("ConsentRequest", function()
    local requester = net.ReadEntity()
    local action = net.ReadString()
    CreateConsentRequestMenu(requester, action)
end)

-- Функция для создания меню с действиями из категории
local function OpenCategoryMenu(categoryActions, target)
    local menu = CreateRadialMenu() -- Создаем меню

    for name, action in pairs(categoryActions) do
        menu:AddOption(action.displayName, "Выполнить действие", Material("path/to/icon.png"), Color(150, 150, 255), function()
            net.Start("RequestInteraction")
            net.WriteString(name)
            net.WriteEntity(target)
            net.SendToServer()

            -- Закрываем меню после выбора действия
            menu:Close()
            isShowingMenu = false
            targetPlayer = nil
        end)
    end

    -- Открытие меню
    menu:Open()
end

-- Функция для отображения главного радиального меню с категориями
local function OpenMainRadialMenu(target)
    local menu = CreateRadialMenu() -- Создаем новое меню через аддон

    -- Добавляем категории в меню
    menu:AddOption("Другие действия", "Выберите из списка других действий", Material("path/to/icon.png"), Color(255, 150, 150), function()
        OpenCategoryMenu(InteractionsConfig.OtherActions, target)
        menu:Close() -- Закрываем главное меню после открытия подменю
    end)

    menu:AddOption("Дружелюбные действия", "Выберите дружелюбные действия", Material("path/to/icon.png"), Color(150, 255, 150), function()
        OpenCategoryMenu(InteractionsConfig.FriendlyActions, target)
        menu:Close()
    end)

    menu:AddOption("Медицинские действия", "Выберите медицинские действия", Material("path/to/icon.png"), Color(150, 255, 150), function()
        OpenCategoryMenu(InteractionsConfig.MedicalActions, target)
        menu:Close()
    end)

    menu:AddOption("Недружелюбные действия", "Выберите недружелюбные действия", Material("path/to/icon.png"), Color(255, 150, 150), function()
        OpenCategoryMenu(InteractionsConfig.SexActions, target)
        menu:Close()
    end)

    -- Открытие меню
    menu:Open()
end

-- Вызов вложенного меню
local function OpenNestedCategoryMenu(target)
    local menu = CreateRadialMenu()

    local subMenuHolder = menu:AddOption("Вложенное меню", "Описание", Material("path/to/icon.png"), Color(255, 200, 200))

    -- Добавляем опции во вложенное меню
    subMenuHolder:AddSubOption("Опция 1", "Описание 1", Material("path/to/icon1.png"), Color(200, 255, 150), function() print("Опция 1 выбрана") end)
    subMenuHolder:AddSubOption("Опция 2", "Описание 2", Material("path/to/icon2.png"), Color(150, 255, 200), function() print("Опция 2 выбрана") end)

    -- Открываем главное меню
    menu:Open()
end

-- Функция для рисования кнопки "G" над игроками
local function DrawGButton(player)
    local pos = player:LocalToWorld(player:OBBCenter()):ToScreen()
    draw.SimpleText("G", "Trebuchet24", pos.x, pos.y, Color(255, 255, 255, 255), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end

-- Проверка, находится ли игрок в поле зрения
local function IsPlayerInFOV(ply)
    local localPlayer = LocalPlayer()
    local forward = localPlayer:EyeAngles():Forward()
    local direction = (ply:GetPos() - localPlayer:GetPos()):GetNormalized()
    local dot = forward:Dot(direction)

    local angle = math.deg(math.acos(dot))
    return angle <= (interactionFOV / 2)
end

-- Функция для проверки попадания трассировки на игрока
local function TraceForPlayer()
    local localPlayer = LocalPlayer()
    local trace = util.TraceLine({
        start = localPlayer:EyePos(),
        endpos = localPlayer:EyePos() + localPlayer:GetAimVector() * interactionRadius,
        filter = localPlayer
    })

    if trace.Hit and IsValid(trace.Entity) and trace.Entity:IsPlayer() then
        return trace.Entity
    end

    return nil
end

-- Хук для рисования кнопки "G" на HUD
hook.Add("HUDPaint", "ShowGKeyOnClosePlayers", function()
    if isShowingMenu then return end -- Проверяем, не открыто ли уже меню

    local localPlayer = LocalPlayer()

    local tracedPlayer = TraceForPlayer()

    if IsValid(tracedPlayer) and tracedPlayer:Alive() and IsPlayerInFOV(tracedPlayer) then
        DrawGButton(tracedPlayer) -- Рисуем кнопку "G"
        targetPlayer = tracedPlayer -- Устанавливаем игрока как цель
    else
        targetPlayer = nil -- Сбрасываем цель, если игрок не найден
    end
end)

-- Хук для проверки нажатия кнопки "G"
hook.Add("Think", "CheckGKeyPress", function()
    local localPlayer = LocalPlayer()

    -- Проверка, что фокус не находится на элементе ввода текста и игра не в паузе
    if not vgui.GetKeyboardFocus() and not gui.IsGameUIVisible() and input.IsKeyDown(KEY_G) and targetPlayer then
        if not isShowingMenu then -- Проверяем, не открыто ли уже меню
            isShowingMenu = true
            OpenMainRadialMenu(targetPlayer) -- Открываем главное меню
        end
    end

    -- Обновляем состояние меню и игрока, если меню закрыто
    if isShowingMenu and targetPlayer then
        local distance = localPlayer:GetPos():Distance(targetPlayer:GetPos())
        if distance > interactionRadius then
            isShowingMenu = false
            targetPlayer = nil
        end
    end
end)

-- Функция для закрытия меню
local function CloseRadialMenu(frame)
    if IsValid(frame) then
        frame:Close()
    end
    isShowingMenu = false
    targetPlayer = nil
end

-- Функция для рисования круга
function draw.Circle(x, y, radius, seg)
    local cir = {}
    table.insert(cir, {x = x, y = y})

    for i = 0, seg do
        local a = math.rad((i / seg) * -360)
        table.insert(cir, {x = x + math.sin(a) * radius, y = y + math.cos(a) * radius})
    end

    surface.DrawPoly(cir)
end

-- Уведомление о завершении клиентской загрузки
print("Client-side Interaction Menu loaded.")

Когда действие выполнилось, я не могу нажать ещё раз кнопку G. Мне нужно сначала отбежать а потом прибежать обратно, чтобы она появилась и я смог бы открыть меню