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

AnWu

Известный
Всефорумный модератор
4,780
5,412
Я уже по другому придумал:

Lua:
        imgui.InputText('playerSkin', setPlayerSkin)
        imgui.SameLine()
        if imgui.Button('Set') then
            requestModel(setPlayerSkin.v)
            loadAllModelsNow()
            setPlayerModel(PLAYER_HANDLE, setPlayerSkin.v)
        end
Нет ли в imgui InputText, но только для чисел?
Тип ImInt нужен и да есть. InputInt(name, intBuffer)
Код:
IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0);
 
  • Нравится
Реакции: checkdasound

f0rtrix

Известный
208
15
Можно ли как-то выключить скрипт, а после перезагрузки samp он снова начнет работать? Допустим по написанию команды.
 

#Northn

Pears Project — уже запущен!
Всефорумный модератор
2,652
2,550
Можно ли как-то выключить скрипт, а после перезагрузки samp он снова начнет работать? Допустим по написанию команды.
Свой скрипт:
Lua:
thisScript():unload()
Если другой скрипт - находим его по
Lua:
totscript = script.find('Здесь название скрипта из script_name')
И потом
Lua:
totscript:unload()
 

imring

Ride the Lightning
Всефорумный модератор
2,366
2,556
Lua:
   while true do
        wait(0)
        if isPlayerPlaying(playerHandle) then
            if enabled then
                if selector_point then
                    selectpoint[math.random(1, #selectpoint)]
                    selector_point = false
                end
Код:
[14:55:21.715792] (error)    FactoryBot.lua: C:\Games\GTA\GTA\moonloader\FactoryBot.lua:123: '=' expected near 'selector_point'
[14:55:21.715792] (error)    FactoryBot.lua: Script died due to an error. (17185E3C)
Lua:
--[[
    > FactoryBot for Diamond Role Play
    > Author:        headcliff
    > Version:         0.1
    > Activate:     /drp_factory
    > URL site:     blast.hk/
--]]

script_name("FactoryBot")

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

local selectpoint = {
    right_point = true,
    left_point = true
}

local selecttable_left = {
    table1 = true,
    table2 = true,
    table3 = true,
    table4 = true,
    table5 = true
}

local selecttable_right = {
    table6 = true,
    table7 = true,
    table8 = true,
    table9 = true,
    table10 = true
}

local selecttable_left1 = {
    table2 = true,
    table3 = true,
    table4 = true,
    table5 = true
}

local selecttable_left2 = {
    table1 = true,
    table3 = true,
    table4 = true,
    table5 = true
}

local selecttable_left3 = {
    table1 = true,
    table2 = true,
    table4 = true,
    table5 = true
}

local selecttable_left4 = {
    table1 = true,
    table2 = true,
    table3 = true,
    table5 = true
}

local selecttable_left5 = {
    table1 = true,
    table2 = true,
    table3 = true,
    table4 = true
}

local selecttable_right6 = {
    table7 = true,
    table8 = true,
    table9 = true,
    table10 = true
}

local selecttable_right7 = {
    table6 = true,
    table8 = true,
    table9 = true,
    table10 = true
}

local selecttable_right8 = {
    table6 = true,
    table7 = true,
    table9 = true,
    table10 = true
}

local selecttable_right9 = {
    table6 = true,
    table7 = true,
    table8 = true,
    table10 = true
}

local selecttable_right10 = {
    table6 = true,
    table7 = true,
    table8 = true,
    table9 = true
}

function main()
    if not isSampLoaded() and not isSampfuncsLoaded then return end
    while not isSampAvailable() do wait(0) end
    print('Скрипт был успешно загружен.')
    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Скрипт был успешно загружен.', -1)
    sampRegisterChatCommand("drp_factory", cmd_1)
    sampRegisterChatCommand("obj", cmd_2)
    sampRegisterChatCommand("anim", cmd_3)

    local saveX = {}
    local saveY = {}
    local saveZ = {}
    while true do
        wait(0)
        if isPlayerPlaying(playerHandle) then
            if enabled then
                if selector_point then
                    selectpoint[math.random(1, #selectpoint)]
                    selector_point = false
                end
                if left_point then
                    left_side = true
                    point1 = true
                    left_point = false
                end
                if point1 then
                    -- бег к поинт1
                    point1 = false
                end
                if point2 then
                    -- бег к поинт2
                    left_side = false
                    left_side2 = true
                    point2 = false
                end
                if point3 then
                    -- бег к поинт3
                    left_side2 = false
                    left_side3 = true
                    point3 = false
                end
                if point3to2 then
                    -- бег к поинт2 с поинт3
                    left_side3 = false
                    left_side3to2 = true
                    point3to2 = false
                end
                if point2to1 then
                    -- бег к поинт1 с поинт2
                    left_side3to2 = false
                    left_side = true
                    point2to1 = false
                end
                if right_point then
                    right_side = true
                    point4 = true
                    right_point = false
                end
                if point4 then
                    -- бег к поинт4
                    point4 = false
                end
                if point5 then
                    -- бег к поинт5
                    right_side = false
                    right_side2 = true
                    point5 = false
                end
                if point6 then
                    -- бег к поинт6
                    right_side5 = false
                    right_side6 = true
                    point3 = false
                end
                if point6to5 then
                    -- бег к поинт5 с поинт6
                    right_side6 = false
                    right_side6to5 = true
                    point6to5 = false
                end
                if point5to4 then
                    -- бег к поинт4 с поинт5
                    right_side6to5 = false
                    right_side = true
                    point5to4 = false
                end
                if gototable_left then
                    selecttable_left[math.random(1, #selecttable_left)]
                end
                if gototable_right then
                    selecttable_right[math.random(1, #selecttable_right)]
                end
                if table1 then
                    -- бег к столу1
                    itleftside1 = true
                    wait(500)
                    table1 = false
                end
                if table2 then
                    -- бег к столу2
                    itleftside1 = true
                    wait(500)
                    table2 = false
                end
                if table3 then
                    -- бег к столу3
                    itleftside1 = true
                    wait(500)
                    table3 = false
                end
                if table4 then
                    -- бег к столу4
                    itleftside2 = true
                    wait(500)
                    table4 = false
                end
                if table5 then
                    -- бег к столу5
                    itleftside2 = true
                    wait(500)
                    table5 = false
                end
                if table6 then
                    -- бег к столу6
                    itrightside1 = true
                    wait(500)
                    table6 = false
                end
                if table7 then
                    -- бег к столу7
                    itrightside1 = true
                    wait(500)
                    table7 = false
                end
                if table8 then
                    -- бег к столу8
                    itrightside1 = true
                    wait(500)
                    table8 = false
                end
                if table9 then
                    -- бег к столу9
                    itrightside2 = true
                    wait(500)
                    table8 = false
                end
                if table10 then
                    -- бег к столу10
                    itrightside2 = true
                    wait(500)
                    table8 = false
                end
            end
        end
    end
end

function sampev.onServerMessage(color, text)
    if enabled then
        if text:find('На данной точке нет материала') then -- изменить текст на правильный
            if left_side then
                point2 = true
                return
            end
            if left_side2 then
                point3 = true
                return
            end
            if left_side3 then
                point3to2 = true
                return
            end
            if left_side3to2 then
                point2to1 = true
                return
            end
            if right_side then
                point5 = true
                return
            end
            if right_side5 then
                point6 = true
                return
            end
            if right_side6 then
                point6to5 = true
                return
            end
            if right_side6to5 then
                point5to4 = true
                return
            end
        end
        if text:find('Стол занят') then -- изменить текст на правильный
            if table1 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_left1[math.random(1, #selecttable_left1)]
                return
            end
            if table2 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_left2[math.random(1, #selecttable_left2)]
                return
            end
            if table3 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_left3[math.random(1, #selecttable_left3)]
                return
            end
            if table4 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_left4[math.random(1, #selecttable_left4)]
                return
            end
            if table5 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_left5[math.random(1, #selecttable_left5)]
                return
            end
            if table6 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_right6[math.random(1, #selecttable_left6)]
                return
            end
            if table7 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_right7[math.random(1, #selecttable_right7)]
                return
            end
            if table8 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_right8[math.random(1, #selecttable_right8)]
                return
            end
            if table9 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_right9[math.random(1, #selecttable_right9)]
                return
            end
            if table10 then
                -- бег в сторону от стола (чтобы во время бега к другому столу не брал метки других по пути)
                selecttable_right10[math.random(1, #selecttable_right10)]
                return
            end
        end
    end
end

function sampev.onAttachObjectToPlayer(objectId, playerId, offsets, rotation)
    if enabled and objectId = ??? then -- изменить ИД ОБЪЕКТА
        if left_side or left_side2 or left_side3 or left_side3to2 then
            left_side = false
            left_side2 = false
            left_side3 = false
            left_side3to2 = false
            gototable_left = true
        end
        if right_side or right_side5 or right_side6 or right_side6to5 then
            right_side = false
            right_side5 = false
            right_side6 = false
            right_side6to5 = false
            gototable_right = true
        end
    end
    if test-cmd then
        print(objectId - playerId - offsets - rotation)
        wait(500)
        sampAddChatMessage('{00BFFF}[testcmd]{FFFFFF} Де-активирован.', -1)
        test-cmd = false
    end
end

function sampev.onApplyPlayerAnimation(playerId, animLib, animName, loop, lockX, lockY, freeze, time)
    if enabled and animName == ??? then -- изменить animName
        if itleftside1 then
            -- сдача ближние, левые столы
            selectorpoint = true
            itleftside1 = false
        end
        if itleftside2 then
            -- сдача дальние, левые столы
            selectorpoint = true
            itleftside2 = false
        end
        if itrightside1 then
            -- сдача ближние, правые столы
            selectorpoint = true
            itrightside1 = false
        end
        if itrightside2 then
            -- сдача дальние, правые столы
            selectorpoint = true
            itrightside2 = false
        end
    end
    if test-cmd2 then
        print(playerId - animLib - animName - loop - lockX - lockY - freeze - time)
        sampAddChatMessage('{00BFFF}[testcmd2]{FFFFFF} Де-активирован.', -1)
        test-cmd2 = false
    end
end
          
--------------------------- STANDART FUNCTIONS ---------------------------

function BeginToPoint(x, y, z, radius, move_code, isSprint)
    repeat
        local posX, posY, posZ = GetCoordinates()
        SetAngle(x, y, z)
        MovePlayer(move_code, isSprint)
        local dist = getDistanceBetweenCoords3d(x, y, z, posX, posY, z)
        wait(0)
    until not enabled or dist < radius
end

function MovePlayer(move_code, isSprint)
    setGameKeyState(1, move_code)
    if isSprint then setGameKeyState(16, 255) end
end

function SetAngle(x, y, z)
    local posX, posY, posZ = GetCoordinates()
    local pX = x - posX
    local pY = y - posY
    local zAngle = getHeadingFromVector2d(pX, pY)

    if isCharInAnyCar(playerPed) then
        local car = storeCarCharIsInNoSave(playerPed)
        setCarHeading(car, zAngle)
    else
        setCharHeading(playerPed, zAngle)
    end

    restoreCameraJumpcut()
end

function GetCoordinates()
    if isCharInAnyCar(playerPed) then
        local car = storeCarCharIsInNoSave(playerPed)
        return getCarCoordinates(car)
    else
        return getCharCoordinates(playerPed)
    end
end

function cmd_1(param)
    enabled = not enabled
    if enabled then
        selector1 = true
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Активирован.', -1)
    else
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Де-активирован.', -1)
    end
end

function cmd_2(param)
    test-cmd = not test-cmd
    if test-cmd then
        sampAddChatMessage('{00BFFF}[testcmd]{FFFFFF} Активирован.', -1)
    else
        sampAddChatMessage('{00BFFF}[testcmd]{FFFFFF} Де-активирован.', -1)
    end
end

function cmd_3(param)
    test-cmd2 = not test-cmd2
    if test-cmd2 then
        sampAddChatMessage('{00BFFF}[testcmd2]{FFFFFF} Активирован.', -1)
    else
        sampAddChatMessage('{00BFFF}[testcmd2]{FFFFFF} Де-активирован.', -1)
    end
end

Что-то не соображаю, что он от меня хочет.
selectpoint[math.random(1, #selectpoint)] что ты с этим собираешься делать?
 

Patrickkk

Участник
162
19
Есть варианты работы с базой данных на луа в сампе? Нужно примерно организовать такую систему, имгуи в игре, где показываются какие-либо данные из БД. Такое вообще реально реализовать?
 

AnWu

Известный
Всефорумный модератор
4,780
5,412
Lua:
script_name("FactoryBot")

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

local selectside = {
    rightside,
    leftside
}

function main()
    if not isSampLoaded() and not isSampfuncsLoaded then return end
    while not isSampAvailable() do wait(0) end
    print('Скрипт был успешно загружен.')
    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Скрипт был успешно загружен.', -1)
    sampRegisterChatCommand("drp_factory", cmd_1)

    while true do
        wait(0)
        if isPlayerPlaying(playerHandle) then
            if enabled then
                if selectorside then
                    selectside[math.random(1, #selectside)] = true
                    selectorside = false
                end
                if rightside then
                    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Право.', -1)
                    rightside = false
                end
                if leftside then
                    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Лево.', -1)
                    leftside = false
                end
            end
        end
    end
end

function cmd_1(param)
    enabled = not enabled
    if enabled then
        selectorside = true
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Активирован.', -1)
    else
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Де-активирован.', -1)
    end
end

Почему не работает? (скрипт загружается, активирую /drp_factory и ничего)
Смешной код. Почитай основы скриптинга. Особенно про таблицы
 
  • Нравится
Реакции: imring

T1cKz

Известный
595
245
Lua:
script_name("FactoryBot")

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

local selectside = {
    rightside,
    leftside
}

function main()
    if not isSampLoaded() and not isSampfuncsLoaded then return end
    while not isSampAvailable() do wait(0) end
    print('Скрипт был успешно загружен.')
    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Скрипт был успешно загружен.', -1)
    sampRegisterChatCommand("drp_factory", cmd_1)

    while true do
        wait(0)
        if isPlayerPlaying(playerHandle) then
            if enabled then
                if selectorside then
                    selectside[math.random(1, #selectside)] = true
                    selectorside = false
                end
                if rightside then
                    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Право.', -1)
                    rightside = false
                end
                if leftside then
                    sampAddChatMessage('{00BFFF}[Factory]{FFFFFF} Лево.', -1)
                    leftside = false
                end
            end
        end
    end
end

function cmd_1(param)
    enabled = not enabled
    if enabled then
        selectorside = true
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Активирован.', -1)
    else
        sampAddChatMessage('{00BFFF}[FactoryBot]{FFFFFF} Де-активирован.', -1)
    end
end

Почему не работает? (скрипт загружается, активирую /drp_factory и ничего)
Во первых, в начале добавь переменную local enabled = false
Во вторых, зачем ты делаешь такой тупой рандом? Почему нельзя просто
Lua:
local resul = math.random(1,2)
if resul == 1 then
--лево
elseif resul == 2 then
-- право
end
Зачем делать эти мозгоёбли с таблицами, когда можно сделать проще?
 
  • Нравится
Реакции: maestto

ШPEK

Известный
1,474
526
Как в тексте поставить кавычки чтобы не заменять их "ёлочками" или "одиночными кавычками"
 

samespoon

Известный
163
20
Как в тексте поставить кавычки чтобы не заменять их "ёлочками" или "одиночными кавычками"
Lua:
 -- Сделать так если нужны двойные кавычки:
sampSendChat(' " Текст в двойных кавычках тут  " ')

-- Либо так в случае с одиночными
sampSendChat(" ' Текст в одиночных кавычках тут  ' ")
Пробелы поставил для того, чтобы их было видно, можешь их не ставить.
 

ShuffleBoy

Известный
Друг
753
426
Во первых, в начале добавь переменную local enabled = false
Во вторых, зачем ты делаешь такой тупой рандом? Почему нельзя просто
Lua:
local resul = math.random(1,2)
if resul == 1 then
--лево
elseif resul == 2 then
-- право
end
Зачем делать эти мозгоёбли с таблицами, когда можно сделать проще?
про труе фолсе прочитай
OvercookedButteryDrawing(https://repl.it/repls/OvercookedButteryDrawing)
 
  • Нравится
Реакции: AnWu

checkdasound

Известный
Проверенный
963
410
В функции setCharAccuracy(Ped ped, int accuracy)
Инт отвечает за разброс или точность или что? И какое значение максимальное и стандартное?