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

wqaddfs0

Потрачен
12
36
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Сделал чтобы текста на экране не было по дефолту, но он все равно есть. Как это исправить?
Lua:
local font_flag = require('moonloader').font_flag
local fr = renderCreateFont('Arial', 12, font_flag.BOLD + font_flag.SHADOW)
require "lib.moonloader"
require "lib.sampfuncs"
local enabled = false

function main()
  if not isSampLoaded() and not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(0) end
  sampRegisterChatCommand("enable", enabled)
  while true do
    wait(0)
    if enabled then
    renderFontDrawText(fr, '{FF0000}test [X]', 10, 400, 0xFFFFFFFF)
      if isKeyJustPressed(VK_X) then
            sampSendChat("test")
          end
        end
      end
    end
  

function enabled()
    enabled = not enabled
    sampAddChatMessage(enabled and "[Binder] Включен" or "[Binder] Выключен", -1)
end
 

lorgon

Известный
656
271
Сделал чтобы текста на экране не было по дефолту, но он все равно есть. Как это исправить?
Lua:
local font_flag = require('moonloader').font_flag
local fr = renderCreateFont('Arial', 12, font_flag.BOLD + font_flag.SHADOW)
require "lib.moonloader"
require "lib.sampfuncs"
local enabled = false

function main()
  if not isSampLoaded() and not isSampfuncsLoaded() then return end
  while not isSampAvailable() do wait(0) end
  sampRegisterChatCommand("enable", enabled)
  while true do
    wait(0)
    if enabled then
    renderFontDrawText(fr, '{FF0000}test [X]', 10, 400, 0xFFFFFFFF)
      if isKeyJustPressed(VK_X) then
            sampSendChat("test")
          end
        end
      end
    end
 

function enabled()
    enabled = not enabled
    sampAddChatMessage(enabled and "[Binder] Включен" or "[Binder] Выключен", -1)
end
Почему у тебя функция и переменная называются одинаково?
 
  • Нравится
Реакции: wqaddfs0

Curtis

Участник
282
10
Я скомпилил свой lua, а теперь я не могу его использовать, что делать ?
1650307617362.png
 

Вложения

  • 1650307613446.png
    1650307613446.png
    446 байт · Просмотры: 10

wqaddfs0

Потрачен
12
36
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Как сделать так чтобы скрипт отсчитывал от 30 секунд и это отображалось через renderFontDrawText?
 

sat0ry

Известный
1,092
293
lua:
require 'moonloader'

local inicfg = require 'inicfg'
local directIni = 'ahelper.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        tagadm = '|| T.Osnovatel'
        skin = 99
        admpassword = 'qwerty123'
    },
}, directIni))
inicfg.save(ini, directIni)

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

    while sampIsLocalPlayerSpawned() do
        wait(100)
        sampSendChat('/skin ' .. ini.main.skin)
    end
   
    wait(-1)
end
Че за херня?
C#:
[ML] (error) script.lua: D:\Babetape_LetoGTA\moonloader\script.lua:6: '}' expected (to close '{' at line 8) near 'skin'
[ML] (error) script.lua: Script died due to an error. (1414D48C)
 

Curtis

Участник
282
10

chapo

чопа сребдс // @moujeek
Модератор
8,862
11,551
lua:
require 'moonloader'

local inicfg = require 'inicfg'
local directIni = 'ahelper.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        tagadm = '|| T.Osnovatel'
        skin = 99
        admpassword = 'qwerty123'
    },
}, directIni))
inicfg.save(ini, directIni)

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

    while sampIsLocalPlayerSpawned() do
        wait(100)
        sampSendChat('/skin ' .. ini.main.skin)
    end
  
    wait(-1)
end
Че за херня?
C#:
[ML] (error) script.lua: D:\Babetape_LetoGTA\moonloader\script.lua:6: '}' expected (to close '{' at line 8) near 'skin'
[ML] (error) script.lua: Script died due to an error. (1414D48C)
после каждого элемента в массиве (кроме последнего) надо ставить запятую
1650310377132.png


Как сделать так чтобы скрипт отсчитывал от 30 секунд и это отображалось через renderFontDrawText?
Lua:
local timer = {
    active = false,
    duration = 30,
    start = -1,
    font = renderCreateFont('Arial', 40, 5)
}

function main()
    while not isSampAvailable() do wait(0) end
    sampRegisterChatCommand('timer.start', function(arg)
        timer.active, timer.start, timer.duration = true, os.clock(), tonumber(arg) or 30
    end)
    while true do
        wait(0)
        if timer.active then
            local current_time = math.floor(timer.start - os.clock() + timer.duration + 1)
            renderFontDrawText(timer.font, current_time, 500, 500, 0xFFFFFFFF, 0x90000000)
            if current_time <= 0 then
                timer.active = false
                sampAddChatMessage('Прошло '..timer.duration..' секунд', -1)
            end
        end
    end
end
 
Последнее редактирование:

lorgon

Известный
656
271
а как понять под какую компилировать ?


https://code.google.com/archive/p/luaforwindows/downloads здесь качал самую новую версию
а как понять под какую компилировать ?


https://code.google.com/archive/p/luaforwindows/downloads здесь качал самую новую версию
Компилятор LuaJIT для самых маленьких.
Установка: Распаковать архив с нужной версией в любое место.
Использование: Перетащить .lua-файл на compile.bat. Скомпилированный скрипт с расширением .luac появится рядом с исходником.

Скачать v025 (Download compiler): https://blast.hk/moonloader/files/misc/luajit-compiler.zip
Скачать v026+ (Download compiler): https://blast.hk/moonloader/files/misc/luajit-210-compiler.zip



Декомпилятор LuaJIT.
Установка: Распаковать архив с нужной версией в любое место.
Использование: Перетащить .luac-файл на decompile.bat. Декомпилированный скрипт* с расширением .lua появится рядом с исходником.
*после декомпиляции появляется файл с псевдокодом, такой скрипт не будет работать в игре.
 

Curtis

Участник
282
10
Сделал автообновление, Если есть обнова у меня сначала пишет что нет обновы, а потом чтобы обновить, как так? https://www.blast.hk/threads/77735/ смотрел тут

1650315435609.png
 
Последнее редактирование:

sat0ry

Известный
1,092
293
Lua:
require 'moonloader'

local imgui = require('imgui')
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local inicfg = require 'inicfg'
local directIni = 'ahelper.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        skin = 49,
        admpassword = 'qwerty123',
    },
}, directIni))
inicfg.save(ini, directIni)
        
local window = imgui.ImBool(false)
local skin = imgui.ImBuffer(ini.main.skin, 32)
local admpass = imgui.ImBuffer(ini.main.admpassword, 32768)

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

    while not sampIsLocalPlayerSpawned() do wait(0) end

    sampRegisterChatCommand('test', function()
        window.v = not window.v
        imgui.Process = window.v
    end)
    
    wait(-1)
end
        
function imgui.OnDrawFrame()
    if not window.v then
        imgui.Process = false
    end

    if window.v then
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 1000, 600 -- WINDOW SIZE
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - sizeX / 2, resY / 2 - sizeY / 2), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.Begin('window', window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove)
        
        if imgui.InputText(u8'Скин после входа', skin) then save() end
        
        imgui.End()
    end
end


function save()
    ini.main.skin = skin.v
    inicfg.save(ini, directIni)
end
C++:
[ML] (error) script.lua: D:\Babetape_LetoGTA\moonloader\script.lua:21: sol: no matching function call takes this number of arguments and the specified types
stack traceback:
    [C]: in function 'ImBuffer'
    D:\Babetape_LetoGTA\moonloader\script.lua:21: in main chunk
Помогите пж, уже целый день долблюсь с этим inputText и inicfg
 

sep

Известный
681
76
можно ли не указывать пусть к файлу а указать в какую папку загружать ?
downloadUrlToFile("ссылка", 'moonloader/resource/1')
 

lorgon

Известный
656
271
Lua:
require 'moonloader'

local imgui = require('imgui')
local encoding = require 'encoding'
encoding.default = 'CP1251'
u8 = encoding.UTF8
local inicfg = require 'inicfg'
local directIni = 'ahelper.ini'
local ini = inicfg.load(inicfg.load({
    main = {
        skin = 49,
        admpassword = 'qwerty123',
    },
}, directIni))
inicfg.save(ini, directIni)
     
local window = imgui.ImBool(false)
local skin = imgui.ImBuffer(ini.main.skin, 32)
local admpass = imgui.ImBuffer(ini.main.admpassword, 32768)

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

    while not sampIsLocalPlayerSpawned() do wait(0) end

    sampRegisterChatCommand('test', function()
        window.v = not window.v
        imgui.Process = window.v
    end)
 
    wait(-1)
end
     
function imgui.OnDrawFrame()
    if not window.v then
        imgui.Process = false
    end

    if window.v then
        local resX, resY = getScreenResolution()
        local sizeX, sizeY = 1000, 600 -- WINDOW SIZE
        imgui.SetNextWindowPos(imgui.ImVec2(resX / 2 - sizeX / 2, resY / 2 - sizeY / 2), imgui.Cond.FirstUseEver)
        imgui.SetNextWindowSize(imgui.ImVec2(sizeX, sizeY), imgui.Cond.FirstUseEver)
        imgui.Begin('window', window, imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove)
     
        if imgui.InputText(u8'Скин после входа', skin) then save() end
     
        imgui.End()
    end
end


function save()
    ini.main.skin = skin.v
    inicfg.save(ini, directIni)
end
C++:
[ML] (error) script.lua: D:\Babetape_LetoGTA\moonloader\script.lua:21: sol: no matching function call takes this number of arguments and the specified types
stack traceback:
    [C]: in function 'ImBuffer'
    D:\Babetape_LetoGTA\moonloader\script.lua:21: in main chunk
Помогите пж, уже целый день долблюсь с этим inputText и inicfg
Разве в InputText можно пихать числа? Попробуй перевести их в строки
tostring(ini.main.skin)
 
Последнее редактирование:
  • Нравится
Реакции: sat0ry