Вопросы по 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
 
Последнее редактирование:

Smeruxa

Известный
1,304
683
можно ли как то определить что игра свернута? Моя цель - отсчитать время активной игры и время АФК, может есть другие варианты (хотел через сравнение координат камеры - но вариант не идеальный) - меня совет такой тоже устриот.
 

KiddM

Активный
96
37
Мужики, начал учиться писать на луа, в итоге начал через сублайм, дохожу до момента обучения когда команду создавать, благодаря которой происходит надпись в чат, пишу надпись эту на русском и вижу это.
изображение_2021-02-10_232053.png

изображение_2021-02-10_232246.png

Появляются вместо обычного Русского текста, иероглефы. Прошу, помогите.
 

lemonager

;)
Всефорумный модератор
809
1,702
Мужики, начал учиться писать на луа, в итоге начал через сублайм, дохожу до момента обучения когда команду создавать, благодаря которой происходит надпись в чат, пишу надпись эту на русском и вижу это.
Посмотреть вложение 85946
Посмотреть вложение 85948
Появляются вместо обычного Русского текста, иероглефы. Прошу, помогите.
кодировку windows 1251 поставь
 

Tol4ek

Активный
217
56
как сделать так, чтобы скрипт запомнил значение local color, которую я изменил командой в игре?
 

Hahker

Новичок
27
0
local hook = require 'lib.samp.events'
function hook.onServerMessage(color, text)
if text:find('%[R] <REPORT> (.*)') then
sampSendChat('/ot')
return {text}
end
end
Почему скрипт работает единоразово, потом приходится перезапускать moonloader?
И как сделать так чтобы скрипт работал на кнопку?
 

_ex$tanOr_

Участник
125
19
Ребят, подскажите, что не так? У меня ПКМ нажимается, а вот ЛКМ нет. Не могу понять

Lua:
script_name('fish')
script_authors('Simon Mitchell')
script_version_number(1)

start_game = true

sampev = require("lib.samp.events")
require "lib.sampfuncs"
require "lib.moonloader"
lastnumber = nil
check_number_status = false
send_sms_message = nil
local state = false
local bNotf, notf = pcall(import, "resource/imgui_notf.lua")
local active = false
local keys = require "vkeys"
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local res_effil, effil = pcall(require, 'effil')

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

    print("Simon Mitchell - avtor")
  if start_game then sampAddChatMessage("{FF8C00}[Fish] {FF0000}Разработчик: {20B2AA}Simon Mitchell", -1) end
   sampRegisterChatCommand("fishh", cmd_posad)

   while true do
    wait(0)

   end

end

function sampev.onDisplayGameText(style, time, text)
    if active == true then
        if text == "~w~Press ~g~~k~~PED_LOCK_TARGET~" then
           lua_thread.create(function() 
            wait(1000)
            setVirtualKeyDown(VK_RBUTTON, true)
            wait(1000)
            setVirtualKeyDown(VK_RBUTTON, false)
           end)
        end
        if text == "~w~Press ~g~~k~~PED_FIREWEAPON~" then
         lua_thread.create(function() 
            wait(1000)
            setVirtualKeyDown(VK_LBUTTON, true)
            wait(1000)
            setVirtualKeyDown(VK_LBUTTON, false)
         end)
        end
    end
end



function cmd_posad()
    active = not active
      notf.addNotification(active and "[Fish] Скрипт успешно запустился" or "[Fish] Скрипт был остановлен, затем выключен", 6, 3)
end
 

Tol4ek

Активный
217
56
Как сделать так, чтобы цвет, который я изменил через команду, применлся сразу после изменения, без перезагрузки скрипта?
Lua:
local inicfg = require 'inicfg'
local directIni = "moonloader\\colors.ini"
local acolorONE = inicfg.load(nil, directIni).config.acolor
local acolorTWO = inicfg.load(nil, directIni).config.ecolor

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('acolor', cmd_acolor)
    sampRegisterChatCommand('ecolor', cmd_ecolor)
    sampRegisterChatCommand('ccolor', ccolor)
    while true do
        end
    end
end

function cmd_acolor(arg)
    if arg == '' then
    sampAddChatMessage('Введите цвет в формате HEX кода', -1)
    else
        mainIni = inicfg.load(nil, directIni)
        mainIni.config.acolor = arg
        color = arg
        if inicfg.save(mainIni, directIni) then
            sampAddChatMessage('{'..color..'}Был установлен цвет - '..color, -1)
        end
    end
end

function cmd_ecolor(arg)
    if arg == '' then
    sampAddChatMessage('Введите цвет в формате HEX кода', -1)
    else
        mainIni = inicfg.load(nil, directIni)
        mainIni.config.ecolor = arg
        color = arg
        if inicfg.save(mainIni, directIni) then
            sampAddChatMessage('{'..color..'}Был установлен цвет - '..color, -1)
        end
    end
end

function se.onServerMessage(color, text)
    local name, id, question = text:match("^Вопрос от (.+) ID (%d+): (.+)")
        if text:find("^Вопрос от .+ ID %d+: .+") then
        sampAddChatMessage('{fcff39}[Q] {'..acolorTWO..'}Вопрос от {'..acolorONE..'}'..name..' {'..acolorTWO..'}ID {'..acolorONE..'}'..id..'{'..acolorTWO..'}: {'..acolorONE..'}' ..question, 0xfcff39)
        end
        if text:find("^Вопрос от .+ ID %d+: .+") then
        return false
        end
    local nick_help, nick_ask, otvet = text:match("^От (.+) для (.+): (.+)")
        if text:find("^От .+ для .+: .+") then
        sampAddChatMessage('{fcff39}[A] {'..acolorTWO..'}От {'..acolorONE..'}'..nick_help..' {'..acolorTWO..'}для {'..acolorONE..'}'..nick_ask..'{'..acolorTWO..'}: {'..acolorONE..'}' ..otvet, 0xfcff39)
        end
        if text:find("^От .+ для .+: .+") then
        return false       
        end
    end
 

no3jour

Участник
55
0
Помогите исправит ошибки
PHP:
[13:55:34.710128] (error)    test.lua: C:\GTA Black Russia\moonloader\test.lua:12: attempt to index local 'pos' (a nil value)
stack traceback:
    C:\GTA Black Russia\moonloader\test.lua:12: in function 'Selector'
    C:\GTA Black Russia\moonloader\test.lua:40: in function 'OnDrawFrame'

Код:

Код:
local imgui = require 'imgui'
local key = require 'vkeys'
-- одно из основных отличий от оригинального апи
-- все переменные, значения которых записываются в ImGui по указателю, могут использоваться только через специальные типы
local main_window_state = imgui.ImBool(false)
function imgui.Selector(labels, size, selected, pos, speed)
    local rBool = false
    if not speed then speed = 10 end
    if (pos.v < (selected.v * size.y)) then
        pos.v = pos.v + speed
    elseif (pos.v > (selected.v * size.y)) then
        pos.v = pos.v - speed
    end
    imgui.SetCursorPos(imgui.ImVec2(0.00, pos.v))
    local draw_list = imgui.GetWindowDrawList()
    local p = imgui.GetCursorScreenPos()
    local radius = size.y * 0.50
    draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + radius + 1 * (size.x - radius * 2.0), p.y + radius*2), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.ButtonActive]))
    draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + 5, p.y + size.y), imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.Button]), 0)
    draw_list:AddCircleFilled(imgui.ImVec2(p.x + radius + 1 * (size.x - radius * 2.0), p.y + radius), radius, imgui.GetColorU32(imgui.GetColorU32(imgui.GetStyle().Colors[imgui.Col.ButtonActive])), radius/10*12)
    for i = 1, #labels do
        imgui.SetCursorPos(imgui.ImVec2(0, (i * size.y)))
        local p = imgui.GetCursorScreenPos()
        if imgui.InvisibleButton(labels[i], size) then selected.v = i rBool = true end
        if imgui.IsItemHovered() then
            draw_list:AddRectFilled(imgui.ImVec2(p.x-size.x/2, p.y), imgui.ImVec2(p.x + size.x, p.y + size.y), imgui.GetColorU32(imgui.ImVec4(0.58, 0.34, 0.46, 0.20)), radius/10*12)
        end
        imgui.SetCursorPos(imgui.ImVec2(20, (i * size.y + (size.y-imgui.CalcTextSize(labels[i]).y)/2)))
        imgui.Text(labels[i])
    end
    return rBool
end
function imgui.OnDrawFrame()
  if main_window_state.v then -- чтение и запись значения такой переменной осуществляется через поле v (или Value)
    imgui.Begin('##window', _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoScrollbar)
        if imgui.Selector(menu, imgui.ImVec2(130, 50), selected_label, selector_pos, 10) then print('Вы переключили меню на пункт '..selected_label.v) end
        imgui.SetCursorPos(imgui.ImVec2(140, 0))
        imgui.BeginChild('main', imgui.ImVec2(400, 300), true)
            imgui.Text(menu[selected_label.v])
            if selected_label.v == 4 then
                imgui.Text(fa.ICON_FA_PAINT_ROLLER)
            end
        imgui.EndChild()
    imgui.End()
  end
end
function main()
  while true do
    wait(0)
    if wasKeyPressed(key.VK_X) then -- активация по нажатию клавиши X
        main_window_state.v = not main_window_state.v -- переключаем статус активности окна, не забываем про .v
    end
    imgui.Process = main_window_state.v -- теперь значение imgui.Process всегда будет задаваться в зависимости от активности основного окна
  end
end