SA:MP Помощь со скриптом

LeClark

Новичок
Автор темы
5
0
Версия SA-MP
  1. 0.3.7-R5
Здравствуйте, я начал изучать ЛУА и решил написать такой скрипт чтобы поиграться с зоной стрима, тут есть что не работает, я бы хотел узнать есть ли тут баги, что 100 процентнов вероятно, и как их можно исправить

script:
script_name("ZoneList")
script_version("1.0")
script_moonloader(026)
script_dependencies("SAMPFUNCS ^5.3")

require 'lib.moonloader'
require 'lib.sampfuncs'
local sampev = require 'samp.events'

local autoCheck, intervalSec = false, 0
local prevPlayers = {}
local notifyNew, notifyMode2 = false, false
local trackedId, trackedName = nil, nil
local trackedList = {}
local checkpoint = nil
local playerMarkers = {}
local activeMarkers = {}


function main()
    while not isSampfuncsLoaded() do wait(0) end
    sampRegisterChatCommand('zones',       zonesList)
    sampRegisterChatCommand('zonesA',      zonesA)
    sampRegisterChatCommand('zonesOnNew',  zonesOnNew)
    sampRegisterChatCommand('zonehelp',    zonehelp)
    sampRegisterChatCommand('zonechase',   zonechaser)
    sampRegisterChatCommand('zonechasel',  zonechases)
    wait(-1)
end

function zonehelp()
    local infotext = "Доступные команды:\n" ..
                     "/zones - Показать список игроков в текущей зоне стрима\n" ..
                     "/zonesA [кол-во секунд] - Включить автоматически обновляющийся список игроков в зоне стрима каждые указанное количество секунд\n" ..
                     "/zonesOnNew - Включить отображение новых игроков в зоне стрима, работает только совместно с /zones или /zonesA. Фильтрация, если игрок уже в зоне стрима\n" ..
                     "/zonesOnNew mode2 - Включить отображение новых игроков каждый раз, когда кто-то появляется в зоне стрима, независимо от всего\n" ..
                     "/zonechase id/nickname marker(0/1) - отслеживать игрока/игроков если они появятся(нулевой параметр) / отслеживать игрока если он появится в зоне стриме с красным маркером который будет пинговать местоположение игрока каждые 3 секунды"
    sampShowDialog(1000, "Информация/Помощь по использованию ZoneList (1.0)", infotext, "Закрыть", "Ок", 0)
end

function zonechaser(param)
    if not param or param == '' then
        sampAddChatMessage("Использование: /zonechase [ID или ник] [marker]", -1)
        return
    end
    local args = split(param, ' ')
    local key = tostring(args[1]:lower())
    local useMarker = args[2] and args[2]:lower() == 'marker'

    if trackedList[key] then
        trackedList[key] = nil
        trackedMarkers[key] = nil
        sampAddChatMessage(string.format("Слежение отключено: %s", args[1]), -1)
    else
        trackedList[key] = true
        if useMarker then
            trackedMarkers[key] = true
        end
        sampAddChatMessage(string.format("Будет отслеживаться: %s", args[1]), -1)
    end
end

function setMarker(type, x, y, z, radius, color)
    if marker then
        deleteCheckpoint(marker)
        removeBlip(checkpoint)
    end
    checkpoint = addBlipForCoord(x, y, z)
    marker = createCheckpoint(type, x, y, z, 1, 1, 1, radius)
    changeBlipColour(checkpoint, color)
    lua_thread.create(function()
        repeat
            wait(0)
            local px, py, pz = getCharCoordinates(PLAYER_PED)
        until getDistanceBetweenCoords3d(x, y, z, px, py, pz) < radius or not doesBlipExist(checkpoint)
        deleteCheckpoint(marker)
        removeBlip(checkpoint)
        addOneOffSound(0, 0, 0, 1149)
    end)
end


function zonechases()
    sampAddChatMessage("=== Список трекинга ===", -1)
    local any = false
    for k in pairs(trackedList) do
        sampAddChatMessage(" • "..k, -1)
        any = true
    end
    if not any then
        sampAddChatMessage("Никто не отслеживается.", -1)
    end
    sampAddChatMessage("=======================", -1)
end
sampRegisterChatCommand('zonelistchase', zonechases)

local function scanPlayers()
    local t = {}
    for _, h in ipairs(getAllChars()) do
        local ok, id = sampGetPlayerIdByCharHandle(h)
        if ok then t[id] = sampGetPlayerNickname(id) end
    end
    return t
end

function table.count(t)
    local c = 0 for _ in pairs(t) do c = c + 1 end return c
end

function zonesList()
    local current = scanPlayers()
    sampAddChatMessage("--------------------", -1)
    for id, nick in pairs(current) do
        sampAddChatMessage(string.format("ID: %d | Nickname: %s", id, nick), -1)
    end
    sampAddChatMessage(string.format("Всего игроков в зоне стрима: %d", table.count(current)), -1)
    sampAddChatMessage("--------------------", -1)

    if notifyNew then
        for id, nick in pairs(current) do
            if not prevPlayers[id] then
                sampAddChatMessage(
                  string.format("Новый игрок в зоне стрима: ID %d | %s", id, nick),
                  -1
                )
            end
        end
        prevPlayers = current
    end
end

function zonesA(args)
    local n = tonumber(args)
    if n and n > 0 then
        if autoCheck then
            sampAddChatMessage("Автопроверка уже {00FF00}включена!", -1); return
        end
        autoCheck, intervalSec = true, n
        sampAddChatMessage(("Автопроверка включена: каждые %d сек."):format(n), -1)
        lua_thread.create(function()
            while autoCheck do
                zonesList()
                wait(intervalSec * 1000)
            end
        end)
    else
        if autoCheck then
            autoCheck = false
            sampAddChatMessage("Автопроверка {FF0000}выключена.", -1)
        else
            sampAddChatMessage("Укажите интервал: /zonesA 10", -1)
        end
    end
end

function zonesOnNew(args)
    if args == "mode2" then
        notifyMode2 = not notifyMode2
        sampAddChatMessage(
          notifyMode2 and "Mode2 (стрим) {00FF00}ВКЛЮЧЕН" or
                         "Mode2 (стрим) {FF0000}ВЫКЛЮЧЕН",-1)
        return
    end

    notifyNew = not notifyNew
    if notifyNew then
        prevPlayers = scanPlayers()
        sampAddChatMessage("Оповещение о новых игроках (режим 1) {00FF00}ВКЛЮЧЕНО.", -1)
    else
        sampAddChatMessage("Оповещение о новых игроках (режим 1) {FF0000}ВЫКЛЮЧЕНО.", -1)
    end
end

function sampev.onPlayerStreamIn(playerid, forplayerid)
    if playerid == forplayerid then
        return true
    end

    local nick = sampGetPlayerNickname(playerid)
    local ok, ped = sampGetCharHandleBySampPlayerId(playerid)

    if ok and ped and ped ~= 0 then
        if notifyMode2 then
            local x, y, z = getCharCoordinates(ped)
            local screenX, screenY = convert3DCoordsToScreen(x, y, z)
            sampAddChatMessage(
                string.format("{FFFFFF}Новый игрок в зоне стрима: ID %d | %s | Координаты: %.2f, %.2f, %.2f", playerid, nick, x, y, z),1)
        end

        local idKey   = tostring(playerid)
        local nameKey = nick:lower()
        if trackedList[idKey] or trackedList[nameKey] then
            sampAddChatMessage(
              string.format("{FFFF00}Tracked: ID %d | %s", playerid, nick),
              1
            )
            if (trackedMarkers[idKey] or trackedMarkers[nameKey]) and not activeMarkers[playerid] then
                activeMarkers[playerid] = true
                lua_thread.create(function()
                    while true do
                        SetMarker(playerid)
                        wait(3000)
                    end
                end)
            end
        end
    end

    return true
end