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

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,652
2,550
На муне 0.25 и на старом imgui было всё норм, на 0.26 и новый imgui перешёл - это
[12:59:10.234089] (error) PHelper: C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1101: stack index 1, expected string, received number: (bad argument into 'void(const char*)')
stack traceback:
[C]: in function 'Text'
C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1101: in function 'OnDrawFrame'
D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1377: in function <D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1366>
[12:59:10.235089] (error) PHelper: Script died due to an error. (0B86CC7C)
Скрипт не скомпилирован.
Lua:
if show_moon_imgui_tutorial[8].v then
    if gowd then
        local sw, sh = getScreenResolution()
        local btn_size = imgui.ImVec2(-0.1, 0)
        -- center
        if posofw == 1 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.145, sh / 1.27), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        elseif posofw == 2 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / -1, sh / 1.80), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        elseif posofw == 3 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.145, sh / 1.80), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        end
        if wdsize == 1 then
            imgui.SetNextWindowSize(imgui.ImVec2(345, 310), imgui.Cond.FirstUseEver)
        elseif wdsize == 2 then
            imgui.SetNextWindowSize(imgui.ImVec2(345, 260), imgui.Cond.FirstUseEver)
        end
        imgui.Begin(u8'Преступники в зоне стрима', show_moon_imgui_tutorial[8], imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoTitleBar)
        imgui.Text(u8'Преступники в зоне стрима')
        imgui.Separator()
        imgui.Text(' ')
        wdplayers = 0
        imgui.Columns(3)
        imgui.Separator()
        imgui.SetColumnWidth(-1, 175); imgui.Text(u8'Ник'); imgui.NextColumn()
        imgui.SetColumnWidth(-1, 80); imgui.Text(u8'Уровень р.'); imgui.NextColumn()
        imgui.SetColumnWidth(-1, 100); imgui.Text(u8'Дистанция'); imgui.NextColumn()
        imgui.Separator()
        for _, h in pairs(getAllChars()) do
            for _, l in pairs(sust) do
                local _ , id = sampGetPlayerIdByCharHandle(h)
                local _ , m = sampGetPlayerIdByCharHandle(PLAYER_PED)
                if id ~= -1 and id ~= m and doesCharExist(h) and sampIsPlayerConnected(id) then
                    if not isCurrentCharWeapon(h, 34)then
                        local x, y, z = getCharCoordinates(h)
                        local mx, my, mz = getCharCoordinates(PLAYER_PED)
                        local dist = getDistanceBetweenCoords3d(mx, my, mz, x, y, z)
                        local color = string.format("%06X", ARGBtoRGB(sampGetPlayerColor(id)))
                        local nicksu, idsu = l:match('.+%{FFFFFF%} (%a+_%a+)%[(%d+)%].+')
                        local sulvl = l:match('.+Ур. Розыска:{ff0000} (%d+)')
                        local colori = sampGetPlayerColor(id)
                        local r, g, b = bitex.bextract(colori, 16, 8), bitex.bextract(colori, 8, 8), bitex.bextract(colori, 0, 8)
                        local imgui_RGBA = imgui.ImVec4(r / 255.0, g / 255.0, b / 255.0, 1)
                        local colorh = string.sub(string.format('%x', sampGetPlayerColor(id)), 3)
                        if colorh ~= 'ffff' then
                            if tonumber(idsu) == tonumber(id) then
                                wdplayers = wdplayers + 1
                                imgui.SetColumnWidth(-1, 175); imgui.TextColored(imgui_RGBA, nicksu); imgui.SameLine(nil, 0) imgui.Text(' ['..idsu..']') imgui.NextColumn()
                                imgui.SetColumnWidth(-1, 80); imgui.Text(sulvl); imgui.NextColumn()
    --[[1101 строка:]]    imgui.SetColumnWidth(-1, 100); imgui.Text(math.floor(dist)); imgui.NextColumn()
                            end
                        end
                    end
                end
            end
        end
        if wdplayers == 0 then
            imgui.Columns(1)
            imgui.Text(u8"Никого из преступников в зоне стрима нет.")
        end
        imgui.Separator()
        imgui.End()
    end
end
 

#kerosin

🔥
Проверенный
241
155
: opcode '03C0' call caused an unhandled exception
stack traceback:
[C]: in function 'storeCarCharIsInNoSave'
240: local veh = storeCarCharIsInNoSave(PLAYER_PED)
Lua:
function main()
local veh = storeCarCharIsInNoSave(PLAYER_PED)
    while not isSampAvailable() do wait(0) end
    while true do
    wait(0)
-- code
        if gmCar.v and isCharInAnyCar(PLAYER_PED) then
            setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
            setCarCanBeDamaged(veh, not gmCar.v)
        end
-- code
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    while true do
    wait(0)
-- code
        if gmCar.v and isCharInAnyCar(PLAYER_PED) then
            local veh = storeCarCharIsInNoSave(PLAYER_PED)
            setCarProofs(veh, gmCar.v, gmCar.v, gmCar.v, gmCar.v, gmCar.v)
            setCarCanBeDamaged(veh, not gmCar.v)
        end
-- code
 
  • Нравится
Реакции: checkdasound

RTD

Потужно
Модератор
402
475
На муне 0.25 и на старом imgui было всё норм, на 0.26 и новый imgui перешёл - это
[12:59:10.234089] (error) PHelper: C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1101: stack index 1, expected string, received number: (bad argument into 'void(const char*)')
stack traceback:
[C]: in function 'Text'
C:\Users\ediro\AppData\Local\Temp\PHelperTEST.lua:1101: in function 'OnDrawFrame'
D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1377: in function <D:\Games\GTA San Andreas\moonloader\lib\imgui.lua:1366>
[12:59:10.235089] (error) PHelper: Script died due to an error. (0B86CC7C)
Скрипт не скомпилирован.
Lua:
if show_moon_imgui_tutorial[8].v then
    if gowd then
        local sw, sh = getScreenResolution()
        local btn_size = imgui.ImVec2(-0.1, 0)
        -- center
        if posofw == 1 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.145, sh / 1.27), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        elseif posofw == 2 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / -1, sh / 1.80), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        elseif posofw == 3 then
            imgui.SetNextWindowPos(imgui.ImVec2(sw / 1.145, sh / 1.80), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
        end
        if wdsize == 1 then
            imgui.SetNextWindowSize(imgui.ImVec2(345, 310), imgui.Cond.FirstUseEver)
        elseif wdsize == 2 then
            imgui.SetNextWindowSize(imgui.ImVec2(345, 260), imgui.Cond.FirstUseEver)
        end
        imgui.Begin(u8'Преступники в зоне стрима', show_moon_imgui_tutorial[8], imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoTitleBar)
        imgui.Text(u8'Преступники в зоне стрима')
        imgui.Separator()
        imgui.Text(' ')
        wdplayers = 0
        imgui.Columns(3)
        imgui.Separator()
        imgui.SetColumnWidth(-1, 175); imgui.Text(u8'Ник'); imgui.NextColumn()
        imgui.SetColumnWidth(-1, 80); imgui.Text(u8'Уровень р.'); imgui.NextColumn()
        imgui.SetColumnWidth(-1, 100); imgui.Text(u8'Дистанция'); imgui.NextColumn()
        imgui.Separator()
        for _, h in pairs(getAllChars()) do
            for _, l in pairs(sust) do
                local _ , id = sampGetPlayerIdByCharHandle(h)
                local _ , m = sampGetPlayerIdByCharHandle(PLAYER_PED)
                if id ~= -1 and id ~= m and doesCharExist(h) and sampIsPlayerConnected(id) then
                    if not isCurrentCharWeapon(h, 34)then
                        local x, y, z = getCharCoordinates(h)
                        local mx, my, mz = getCharCoordinates(PLAYER_PED)
                        local dist = getDistanceBetweenCoords3d(mx, my, mz, x, y, z)
                        local color = string.format("%06X", ARGBtoRGB(sampGetPlayerColor(id)))
                        local nicksu, idsu = l:match('.+%{FFFFFF%} (%a+_%a+)%[(%d+)%].+')
                        local sulvl = l:match('.+Ур. Розыска:{ff0000} (%d+)')
                        local colori = sampGetPlayerColor(id)
                        local r, g, b = bitex.bextract(colori, 16, 8), bitex.bextract(colori, 8, 8), bitex.bextract(colori, 0, 8)
                        local imgui_RGBA = imgui.ImVec4(r / 255.0, g / 255.0, b / 255.0, 1)
                        local colorh = string.sub(string.format('%x', sampGetPlayerColor(id)), 3)
                        if colorh ~= 'ffff' then
                            if tonumber(idsu) == tonumber(id) then
                                wdplayers = wdplayers + 1
                                imgui.SetColumnWidth(-1, 175); imgui.TextColored(imgui_RGBA, nicksu); imgui.SameLine(nil, 0) imgui.Text(' ['..idsu..']') imgui.NextColumn()
                                imgui.SetColumnWidth(-1, 80); imgui.Text(sulvl); imgui.NextColumn()
    --[[1101 строка:]]    imgui.SetColumnWidth(-1, 100); imgui.Text(math.floor(dist)); imgui.NextColumn()
                            end
                        end
                    end
                end
            end
        end
        if wdplayers == 0 then
            imgui.Columns(1)
            imgui.Text(u8"Никого из преступников в зоне стрима нет.")
        end
        imgui.Separator()
        imgui.End()
    end
end
Это значит ошибка типов. Делай tostring где выходит число.
Lua:
--[[1101 строка:]]    imgui.SetColumnWidth(-1, 100); imgui.Text(tostring(math.floor(dist))); imgui.NextColumn()
 

Aralone

Участник
30
5
Подскажите, пож-та, как правильно записывать значения в память?
Допустим, хочу поставить скорость игры на 150 процентов
Код:
memory.setfloat(B7CB64, 1.5, true)
— не работает
Пробовал также разморозить окно, чтобы работала игра в свернутом режиме, в итоге получается так - я устанавливаю значение на 1 и игра сразу же меняет это значение на свое (на 0). Как сделать правильно? При этом, если делать эти манипуляции через CE, то все работает
 

WhiteWolf

Участник
141
6
Привет народ, подскажите пожалуйста как отловить момент стрельбы в текстуру ? и чтобы в чат писало Ник, попал в текстуру (№текстуры)
 

Mirrorka

Известный
Всефорумный модератор
889
1,381
зачем в беск. цикл хук?? :thinking:
я в код даже не смотрел, у него так было так и осталось. я ебанул просто local sampev = require 'lib.samp.events'
Тестил деньги, гравитацию без приставки - все работало. + как я говорил выше, значение заморозки окна меняется, но не закрепляется навсегда.
а тебе необходимо?
 

Aralone

Участник
30
5
я в код даже не смотрел, у него так было так и осталось. я ебанул просто local sampev = require 'lib.samp.events'

а тебе необходимо?
Конечно, я же хочу сделать работу игры независимо от того, свернута она или нет. Скорость игры не изменяется совсем
 

tlwsn

Известный
537
85
Lua:
local sampev = require 'lib.samp.events'
local key = require "vkeys"
function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('did', did)
    while true do wait(0) end
end

function did()
    did = sampGetCurrentDialogId()
    sampAddChatMessage(did, -1)
end

function sampev.onShowDialog(id)
    if id == 8900 and wasKeyPressed(key.VK_2) then
        sampSendDialogResponse(id, 1, 2, nil)
    end
end
Что не так в коде? Должно при нажатии кнопки 2 выбирать второй пункт
 

AnWu

Известный
Всефорумный модератор
4,780
5,412
Lua:
local sampev = require 'lib.samp.events'
local key = require "vkeys"
function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('did', did)
    while true do wait(0) end
end

function did()
    did = sampGetCurrentDialogId()
    sampAddChatMessage(did, -1)
end

function sampev.onShowDialog(id)
    if id == 8900 and wasKeyPressed(key.VK_2) then
        sampSendDialogResponse(id, 1, 2, nil)
    end
end
Что не так в коде? Должно при нажатии кнопки 2 выбирать второй пункт
Всё не так. Проверку на кнопку надо в main(). Хук выполняется моментально.
 

lorgon

Известный
656
273
Можно ли силами только moonloader`а скрыть только чат? Если нельзя то как можно не только силами moonloader`а?
 

AnWu

Известный
Всефорумный модератор
4,780
5,412
sampSetChatDisplayMode(int mode)
upload_2018-6-27_14-17-4.png
 
  • Нравится
Реакции: checkdasound

checkdasound

Известный
Проверенный
963
410
Только эта функция отключает весь интерфейс, только что проверил. А ему только чат нужно.
Можно ли силами только moonloader`а скрыть только чат? Если нельзя то как можно не только силами moonloader`а?
0AF8: samp add_message_to_chat "Чат выключен" color 16766720
0B2E: 3@ = read_samp_memory offset 408992 size 2
0B2D: write_samp_memory offset 408992 value 50064 size 2

0B2D: write_samp_memory offset 408992 value 3@ size 2
0AF8: samp add_message_to_chat "Чат включен" color 16766720

Только я хз какой есть аналог 0B2E и 0B2D в луа.