Вопросы по Lua скриптингу

Общая тема для вопросов по разработке скриптов на языке программирования Lua, в частности под MoonLoader.
  • Задавая вопрос, убедитесь, что его нет в списке частых вопросов и что на него ещё не отвечали (воспользуйтесь поиском).
  • Поищите ответ в теме посвященной разработке Lua скриптов в MoonLoader
  • Отвечая, убедитесь, что ваш ответ корректен.
  • Старайтесь как можно точнее выразить мысль, а если проблема связана с кодом, то обязательно прикрепите его к сообщению, используя блок [code=lua]здесь мог бы быть ваш код[/code].
  • Если вопрос связан с MoonLoader-ом первым делом желательно поискать решение на wiki.

Частые вопросы

Как научиться писать скрипты? С чего начать?
Информация - Гайд - Всё о Lua скриптинге для MoonLoader(https://blast.hk/threads/22707/)
Как вывести текст на русском? Вместо русского текста у меня какие-то каракули.
Изменить кодировку файла скрипта на Windows-1251. В Atom: комбинация клавиш Ctrl+Shift+U, в Notepad++: меню Кодировки -> Кодировки -> Кириллица -> Windows-1251.
Как получить транспорт, в котором сидит игрок?
Lua:
local veh = storeCarCharIsInNoSave(PLAYER_PED)
Как получить свой id или id другого игрока?
Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
Как проверить, что строка содержит какой-то текст?
Lua:
if string.find(str, 'текст', 1, true) then
-- строка str содержит "текст"
end
Как эмулировать нажатие игровой клавиши?
Lua:
local game_keys = require 'game.keys' -- где-нибудь в начале скрипта вне функции main

setGameKeyState(game_keys.player.FIREWEAPON, -1) -- будет сэмулировано нажатие клавиши атаки
Все иды клавиш находятся в файле moonloader/lib/game/keys.lua.
Подробнее о функции setGameKeyState здесь: lua - setgamekeystate | BlastHack — DEV_WIKI(https://www.blast.hk/wiki/lua:setgamekeystate)
Как получить id другого игрока, в которого целюсь я?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    -- здесь любые действия с полученным идом игрока
  end
end
Как зарегистрировать команду чата SAMP?
Lua:
-- До бесконечного цикла/задержки
sampRegisterChatCommand("mycommand", function (param)
     -- param будет содержать весь текст введенный после команды, чтобы разделить его на аргументы используйте string.match()
    sampAddChatMessage("MyCMD", -1)
end)
Крашит игру при вызове sampSendChat. Как это исправить?
Это происходит из-за бага в SAMPFUNCS, когда производится попытка отправки пакета определенными функциями изнутри события исходящих RPC и пакетов. Исправления для этого бага нет, но есть способ не провоцировать его. Вызов sampSendChat изнутри обработчика исходящих RPC/пакетов нужно обернуть в скриптовый поток с нулевой задержкой:
Lua:
function onSendRpc(id)
  -- крашит:
  -- sampSendChat('Send RPC: ' .. id)

  -- норм:
  lua_thread.create(function()
    wait(0)
    sampSendChat('Send RPC: ' .. id)
  end)
end
 
Последнее редактирование:

kizn

О КУ)))
Всефорумный модератор
2,405
2,054
deladmin:
    sampRegisterChatCommand('deladmin', function(nickS)
        if nickS ~= '' then
            local f = io.open("moonloader//config//Admins.txt", "w")
            f:write(nickS:gsub(nickS, ''))
            f:close()
        else
            sampAddChatMessage('{FF0000}[Ошибка] {FF8C00}Введите ник!', 0xFFFF0000)
        end
    end)
В чем проблема, почему он удаляет абсолютно все и пишет вместо этого 1, когда мне нужно чтобы он стирал только то, что я пишу
Lua:
    sampRegisterChatCommand('deladmin', function(nickS)
        if nickS ~= '' then
            local f = io.open("moonloader//config//Admins.txt", "w")
            if f then
                local content = f:read("*a")
                if content and content ~= "" then
                    content = content:gsub(nickS, "")
                    f:write(content)
                    f:close()
                end
            end
        else
            sampAddChatMessage('{FF0000}[Ошибка] {FF8C00}Введите ник!', 0xFFFF0000)
        end
    end)
 

William_Roses

Активный
260
26
Lua:
    sampRegisterChatCommand('deladmin', function(nickS)
        if nickS ~= '' then
            local f = io.open("moonloader//config//Admins.txt", "w")
            if f then
                local content = f:read("*a")
                if content and content ~= "" then
                    content = content:gsub(nickS, "")
                    f:write(content)
                    f:close()
                end
            end
        else
            sampAddChatMessage('{FF0000}[Ошибка] {FF8C00}Введите ник!', 0xFFFF0000)
        end
    end)
все равно все отчищает
 

Morse

Потрачен
436
70
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
в чем собственно проблема?
Lua:
        if whauto.v then --переменная
            for getallcar, getallcarid in pairs(getAllVehicles()) do
                xcar, ycar, zcar = getCarCoordinates(getallcarid)

                if isPointOnScreen(xcar, ycar, zcar, 0) then
                    x, y = convert3DCoordsToScreen(xcar, ycar, zcar)
                    _, vehid = sampGetVehicleIdByCarHandle(getallcarid)

                    if rInfo.status then
                        if rInfo.id then
                            getincar, getincarid = sampGetCharHandleBySampPlayerId(rInfo.id)

                            if getincar then
                                curX, curY, curZ = getCharCoordinates(getincarid)
                            else
                                curX, curY, curZ = getCharCoordinates(playerPed)
                            end
                        else
                            curX, curY, curZ = getCharCoordinates(playerPed)
                        end
                    else
                        curX, curY, curZ = getCharCoordinates(playerPed)
                    end

                    getincar = getDistanceBetweenCoords3d(curX, curY, curZ, xcar, ycar, zcar)

                    if allnamecar[getCarModel(getallcarid)] then
                        namecar = allnamecar[getincarid]
                    else
                        namecar = "Неизвестная модель " .. getincarid
                    end

                    if getincar < cfg.main.distwhcar then --distwhcar в конфиге прописан
                        renderFontDrawText(fontcar, namecar .. " [" .. vehid .. "]", x, y, 4294967295.0) --на эту строку ошибка, это 779 строка
                        renderFontDrawText(fontcar, "HP: " .. getCarHealth(getallcarid), x, y + 15, 4294967295.0)
                    end
                end
            end
        end
allnamecar:
allnamecar = {
    [476.0] = "Rustler",
    [479.0] = "Regina",
    [478.0] = "Walton",
    [473.0] = "Dinghy",
    [472.0] = "Coastguard",
    [475.0] = "Sabre",
    [474.0] = "Hermes",
    [469.0] = "Sparrow",
    [468.0] = "Sanchez",
    [471.0] = "Quad",
    [470.0] = "Patriot",
    [465.0] = "RCRaider",
    [464.0] = "RCBaron",
    [467.0] = "Oceanic",
    [466.0] = "Glendale",
    [461.0] = "PCJ-600",
    [460.0] = "Skimmer",
    [463.0] = "Freeway",
    [462.0] = "Faggio",
    [457.0] = "Caddy",
    [456.0] = "Yankee",
    [459.0] = "Berkley'sRCVan",
    [458.0] = "Solair",
    [453.0] = "Reefer",
    [452.0] = "Speeder",
    [455.0] = "Flatbed",
    [449.0] = "Tram",
    [448.0] = "Pizzaboy",
    [454.0] = "Tropic",
    [451.0] = "Turismo",
    [450.0] = "Trailer",
    [513.0] = "Stunt",
    [516.0] = "Nebula",
    [549.0] = "Tampa",
    [551.0] = "Merit",
    [553.0] = "Nevada",
    [555.0] = "Windsor",
    [557.0] = "Monster",
    [559.0] = "Jester",
    [561.0] = "Stratum",
    [563.0] = "Raindance",
    [565.0] = "Flash",
    [567.0] = "Savanna",
    [569.0] = "FreightFlat",
    [571.0] = "Kart",
    [573.0] = "Dune",
    [575.0] = "Broadway",
    [577.0] = "AT-400",
    [579.0] = "Huntley",
    [581.0] = "BF-400",
    [583.0] = "Tug",
    [585.0] = "Emperor",
    [587.0] = "Euros",
    [589.0] = "Club",
    [591.0] = "Trailer",
    [593.0] = "Dodo",
    [595.0] = "Launch",
    [597.0] = "PoliceCar",
    [599.0] = "PoliceRanger",
    [601.0] = "S.W.A.T",
    [603.0] = "Phoenix",
    [605.0] = "SadlerShit",
    [607.0] = "Luggage B",
    [609.0] = "Boxville",
    [574.0] = "Sweeper",
    [572.0] = "Mower",
    [570.0] = "StreakCarriage",
    [568.0] = "Bandito",
    [566.0] = "Tahoma",
    [564.0] = "RCTiger",
    [562.0] = "Elegy",
    [560.0] = "Sultan",
    [558.0] = "Uranus",
    [556.0] = "Monster",
    [554.0] = "Yosemite",
    [552.0] = "Utility",
    [550.0] = "Sunrise",
    [548.0] = "Cargobob",
    [546.0] = "Intruder",
    [544.0] = "Firetruck",
    [542.0] = "Clover",
    [540.0] = "Vincent",
    [538.0] = "Streak",
    [536.0] = "Blade",
    [534.0] = "Remington",
    [532.0] = "Combine",
    [530.0] = "Forklift",
    [528.0] = "FBITruck",
    [526.0] = "Fortune",
    [524.0] = "CementTruck",
    [522.0] = "NRG-500",
    [520.0] = "hydra",
    [518.0] = "Buccaneer",
    [514.0] = "Tanker",
    [512.0] = "Cropduster",
    [611.0] = "UtilityTrailer",
    [613.0] = " G63 AMG",
    [615.0] = "BMW X5",
    [617.0] = "C. Cruze",
    [619.0] = "Porsche 911",
    [576.0] = "Tornado",
    [578.0] = "DFT-30",
    [580.0] = "Stafford",
    [582.0] = "NewsVan",
    [584.0] = "Trailer",
    [586.0] = "Wayfarer",
    [588.0] = "Hotdog",
    [590.0] = "FreightBox",
    [592.0] = "Andromada",
    [594.0] = "RCCam",
    [596.0] = "PoliceCar",
    [598.0] = "PoliceCar",
    [600.0] = "Picador",
    [602.0] = "Alpha",
    [604.0] = "GlendaleShit",
    [606.0] = "Luggage A",
    [608.0] = "Stairs",
    [610.0] = "Tiller",
    [612.0] = "GT63",
    [614.0] = "Audi RS6",
    [616.0] = "C. Corvette",
    [618.0] = "Lexus Lx",
    [620.0] = "Porsche Cayenne",
    [444.0] = "Monster",
    [445.0] = "Admiral",
    [446.0] = "Squalo",
    [447.0] = "Seasparrow",
    [440.0] = "Rumpo",
    [441.0] = "RCBandit",
    [442.0] = "Romero",
    [443.0] = "Packer",
    [436.0] = "Previon",
    [437.0] = "Coach",
    [438.0] = "Cabbie",
    [439.0] = "Stallion",
    [432.0] = "Rhino",
    [433.0] = "Barracks",
    [434.0] = "Hotknife",
    [435.0] = "Trailer",
    [428.0] = "Securicar",
    [429.0] = "Banshee",
    [430.0] = "Predator",
    [431.0] = "Bus",
    [424.0] = "BFInjection",
    [425.0] = "Hunter",
    [426.0] = "Premier",
    [427.0] = "Enforcer",
    [420.0] = "Taxi",
    [421.0] = "Washington",
    [422.0] = "Bobcat",
    [423.0] = "Whoopee",
    [416.0] = "Ambulance",
    [417.0] = "Leviathan",
    [418.0] = "Moonbeam",
    [419.0] = "Esperanto",
    [411.0] = "Infernus",
    [410.0] = "Manana",
    [409.0] = "Stretch",
    [408.0] = "Trashmaster",
    [415.0] = "Cheetah",
    [414.0] = "Mule",
    [413.0] = "Pony",
    [412.0] = "Voodoo",
    [403.0] = "Linerunner",
    [402.0] = "Buffalo",
    [401.0] = "Bravura",
    [400.0] = "Landstalker",
    [407.0] = "Firetruck",
    [406.0] = "Dumper",
    [405.0] = "Sentinel",
    [404.0] = "Perrenial",
    [547.0] = "Primo",
    [545.0] = "Hustler",
    [543.0] = "Sadler",
    [541.0] = "Bullet",
    [539.0] = "Vortex",
    [537.0] = "Freight",
    [535.0] = "Slamvan",
    [533.0] = "Feltzer",
    [531.0] = "Tractor",
    [529.0] = "Willard",
    [527.0] = "Cadrona",
    [525.0] = "TowTruck",
    [523.0] = "HPV1000",
    [521.0] = "FCR-900",
    [519.0] = "Shamal",
    [517.0] = "Majestic",
    [515.0] = "Roadtrain",
    [510.0] = "MountainBike",
    [511.0] = "Beagle",
    [508.0] = "Journey",
    [509.0] = "Bike",
    [506.0] = "SuperGT",
    [507.0] = "Elegant",
    [504.0] = "BloodringBanger",
    [505.0] = "Rancher",
    [502.0] = "HotringRacerA",
    [503.0] = "HotringRacerB",
    [500.0] = "Mesa",
    [501.0] = "RCGoblin",
    [498.0] = "Boxvillde",
    [499.0] = "Benson",
    [496.0] = "BlistaCompact",
    [497.0] = "PoliceMaverick",
    [494.0] = "Hotring",
    [495.0] = "Sandking",
    [492.0] = "Greenwood",
    [493.0] = "Jetmax",
    [490.0] = "FBIRancher",
    [491.0] = "Virgo",
    [488.0] = "NewsChopper",
    [489.0] = "Rancher",
    [486.0] = "Dozer",
    [487.0] = "Maverick",
    [484.0] = "Marquis",
    [485.0] = "Baggage",
    [482.0] = "Burrito",
    [483.0] = "Camper",
    [480.0] = "Comet",
    [481.0] = "BMX",
    [477.0] = "ZR-350"
}

Ошибка:
lua:779: attempt to concatenate global 'namecar' (a nil value)
up
 

kizn

О КУ)))
Всефорумный модератор
2,405
2,054
попробуй эту проверку
Lua:
if allnamecar[getCarModel(getallcarid)] then
    namecar = allnamecar[getincarid]
else
    namecar = "Неизвестная модель " .. getincarid
end

заменить на

Lua:
namecar = "Неизвестная модель " .. getincarid
 
if allnamecar[getCarModel(getallcarid)] then
    namecar = allnamecar[getincarid]
end
 

abnomegd

Активный
335
35
Ну короче хотел сделать если при наводке на игрока и нажатием на какую ту клавишу то вызывалось имгуи окно и там чтобы был 1 раздел история ников. И чтобы когда нажимал то открывалось бы история ников ну тоесть (/history (ник_игрока), чтобы срабатывала это команда.
Вот код:
script:
require "lib.moonloader" -- подключение библиотеки
local keys = require "vkeys"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local main_window_state = imgui.ImBool(false)

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

    sampRegisterChatCommand("imgui", cmd_imgui)

    imgui.Process = false

    -- Блок выполняется один раз после старта сампа

    while true do
        wait(0)

        if main_window_state.v == false then
            imgui.Process = false
        end
        -- Блок выполняющийся бесконечно (пока самп активен)

    end
end

function cmd_imgui(arg)
  main_window_state.v = not main_window_state.v
  imgui.Process = main_window_state.v
end

function imgui.OnDrawFrame()
  imgui.Begin(u8"Helper Menu", main_window_state)
  if imgui.Button(u8'История ников') then
    local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
                sampSendChat('/history '..nickname..'')
  end
  imgui.End()
end
 

Morse

Потрачен
436
70
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
попробуй эту проверку
Lua:
if allnamecar[getCarModel(getallcarid)] then
    namecar = allnamecar[getincarid]
else
    namecar = "Неизвестная модель " .. getincarid
end

заменить на

Lua:
namecar = "Неизвестная модель " .. getincarid

if allnamecar[getCarModel(getallcarid)] then
    namecar = allnamecar[getincarid]
end
772: attempt to concatenate global 'getincarid' (a nil value)
772 это
namecar = "Неизвестная модель " .. getincarid
 

Itachi Uchiha

Участник
124
21
Ну короче хотел сделать если при наводке на игрока и нажатием на какую ту клавишу то вызывалось имгуи окно и там чтобы был 1 раздел история ников. И чтобы когда нажимал то открывалось бы история ников ну тоесть (/history (ник_игрока), чтобы срабатывала это команда.
Вот код:
script:
require "lib.moonloader" -- подключение библиотеки
local keys = require "vkeys"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8

local main_window_state = imgui.ImBool(false)

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

    sampRegisterChatCommand("imgui", cmd_imgui)

    imgui.Process = false

    -- Блок выполняется один раз после старта сампа

    while true do
        wait(0)

        if main_window_state.v == false then
            imgui.Process = false
        end
        -- Блок выполняющийся бесконечно (пока самп активен)

    end
end

function cmd_imgui(arg)
  main_window_state.v = not main_window_state.v
  imgui.Process = main_window_state.v
end

function imgui.OnDrawFrame()
  imgui.Begin(u8"Helper Menu", main_window_state)
  if imgui.Button(u8'История ников') then
    local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
                sampSendChat('/history '..nickname..'')
  end
  imgui.End()
end
Попробуй это, убрал говнокод
try:
require "lib.moonloader" -- подключение библиотеки
local keys = require "vkeys"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local main_window_state = imgui.ImBool(false)

local checkPlayerTarget = {}

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

  sampRegisterChatCommand("imgui", function()
    if checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    else
      sampAddChatMessage("Наведись на игрока",-1)
    end
  end)

  -- Блок выполняется один раз после старта сампа

  while true do
    wait(0)
    checkPlayerTarget[1], checkPlayerTarget[2] = getCharPlayerIsTargeting(PLAYER_HANDLE)
    imgui.Process = main_window_state.v

    if isKeyJustPressed(VK_X) and checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    end
    -- Блок выполняющийся бесконечно (пока самп активен)
  end
end

function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.Begin(u8"Helper Menu", main_window_state)
    if imgui.Button(u8'История ников') then
      if doesCharExist(checkPlayerTarget[2]) then
        local pedId = sampGetPlayerIdByCharHandle(checkPlayerTarget[2])
        local pedNickName = sampGetPlayerNickname(pedId)
        sampSendChat('/history '..pedNickName)
      end
    end
    imgui.End()
  end
end
 
  • Нравится
Реакции: abnomegd

abnomegd

Активный
335
35
Попробуй это, убрал говнокод
try:
require "lib.moonloader" -- подключение библиотеки
local keys = require "vkeys"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local main_window_state = imgui.ImBool(false)

local checkPlayerTarget = {}

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

  sampRegisterChatCommand("imgui", function()
    if checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    else
      sampAddChatMessage("Наведись на игрока",-1)
    end
  end)

  -- Блок выполняется один раз после старта сампа

  while true do
    wait(0)
    checkPlayerTarget[1], checkPlayerTarget[2] = getCharPlayerIsTargeting(PLAYER_HANDLE)
    imgui.Process = main_window_state.v

    if isKeyJustPressed(VK_X) and checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    end
    -- Блок выполняющийся бесконечно (пока самп активен)
  end
end

function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.Begin(u8"Helper Menu", main_window_state)
    if imgui.Button(u8'История ников') then
      if doesCharExist(checkPlayerTarget[2]) then
        local pedId = sampGetPlayerIdByCharHandle(checkPlayerTarget[2])
        local pedNickName = sampGetPlayerNickname(pedId)
        sampSendChat('/history '..pedNickName)
      end
    end
    imgui.End()
  end
end
написал /imgui написал наведись на игрока ну я навелся и нажал X но ничего не пройзошло
 

Itachi Uchiha

Участник
124
21
когда жму история ников то ничего не происходит
Если в консоле нет никаких ошибок - то Хэндла персонажа не существует

1628884229319.png
 
  • Нравится
Реакции: abnomegd

Itachi Uchiha

Участник
124
21
Когда открываю имгуи окно и пропадает наведение на игрока

Lua:
require "lib.moonloader" -- подключение библиотеки
local keys = require "vkeys"
local imgui = require 'imgui'
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local main_window_state = imgui.ImBool(false)

local checkPlayerTarget = {}

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

  sampRegisterChatCommand("imgui", function()
    if checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    else
      sampAddChatMessage("Наведись на игрока",-1)
    end
  end)

  -- Блок выполняется один раз после старта сампа

  while true do
    wait(0)
    if checkPlayerTarget[1] ~= nil and checkPlayerTarget[2] ~= nil then
        checkPlayerTarget[1], checkPlayerTarget[2] = getCharPlayerIsTargeting(PLAYER_HANDLE)
    end
    imgui.Process = main_window_state.v

    if isKeyJustPressed(VK_X) and checkPlayerTarget[1] == true then
      main_window_state.v = not main_window_state.v
    end
    -- Блок выполняющийся бесконечно (пока самп активен)
  end
end

function imgui.OnDrawFrame()
  if main_window_state.v then
    imgui.Begin(u8"Helper Menu", main_window_state)
    if imgui.Button(u8'История ников') then
      if doesCharExist(checkPlayerTarget[2]) then
        local pedId = sampGetPlayerIdByCharHandle(checkPlayerTarget[2])
        local pedNickName = sampGetPlayerNickname(pedId)
        sampSendChat('/history '..pedNickName)
        checkPlayerTarget[1] = nil
        checkPlayerTarget[2] = nil
      end
    end
    imgui.End()
  end
end