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

utmpL

Активный
309
65
Lua:
function main()
  while not isSampAvailable() do
    wait(1000)
  end
sampRegisterChatCommand("rozisk", rozisk) -- Основная команда .
sampRegisterChatCommand("pnanad", pnapad) -- Выдать розыск за нападение на ПО 

function pnapad() --
  local pnanad =
sampSendChat(string.format('/su %d' 6 Нападение на сотрудника ПО, id))
    end
Этого хватит чтоб выдать розыск по указанному id?
Lua:
function main()
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand('pnanad', pnanad)
    repeat wait(0) until false
end

function pnanad(param)
pnanad = tonumber(param)
if param then
    if pnanad ~= nil then
        sampSendChat('/su '..pnanad..' 6 Нападение на сотрудника ПО')
    end
end
end
 

Howl1337

Известный
236
146
Как телепортироваться к ближайшему такому маркеру?
Не sendpic
4S5y5Sr.png
 

Terratomorf

Известный
315
58
Как сделать при появлении в чате надписи "Успех" от сервера то скрипт должен остановится
Код:
require("lib.moonloader")

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        for i = 1000, 10000 do
            sampSendChat("/sur "..i)
        end
    end)
    wait(-1)
end
 

Nishikinov

Известный
148
34
Как телепортироваться к ближайшему такому маркеру?
Не sendpic
4S5y5Sr.png
Один из вариантов, словить onCreatePickup и записывать все пикапы в массив. Затем перебрать массив на дистанцию, взять самый ближний и затем setCharCoordinates.

Как сделать при появлении в чате надписи "Успех" от сервера то скрипт должен остановится
Код:
require("lib.moonloader")

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        for i = 1000, 10000 do
            sampSendChat("/sur "..i)
        end
    end)
    wait(-1)
end
Lua:
local samp = require 'lib.samp.events'

function samp.onServerMessage(color, text)
    if text:find('Успех') then
        activation = false
    end
end

if activation then
    -- код
end
 

checkdasound

Известный
Проверенный
963
406
Как телепортироваться к ближайшему такому маркеру?
Не sendpic
Тебе подобрать нужно или просто телепортироваться? Если тп, то просто находи координаты и телепортируйся.
А если подобрать, то отправляй синхру на координаты и уже sampSendPickedUpPickup, чтобы сервер думал, что ты стоишь на пикапе (код ниже).
Lua:
pickup_id = 322

-- function main while true do
local pickup = sampGetPickupHandleBySampId(pickup_id)
local pickup_x, pickup_y, pickup_z = getPickupCoordinates(pickup)
function sendOnfootSync(pickup_x, pickup_y, pickup_z)
sampSendPickedUpPickup(pickup_id)

function sendOnfootSync(x, y, z)
   local _, myId = sampGetPlayerIdByCharHandle(PLAYER_PED)
   local data = allocateMemory(68)
   sampStorePlayerOnfootData(myId, data)
   setStructFloatElement(data, 6, x, false)
   setStructFloatElement(data, 10, y, false)
   setStructFloatElement(data, 14, z, false)
   sampSendOnfootData(data)
   freeMemory(data)
end
 
  • Нравится
Реакции: ChromiusJ и Howl1337

Chokecha

Новичок
21
1
Синтаксис выучить надо и знать стандартные функции Lua, а остальное со временем придёт.
Вот ссылка на тему, которая помогла в изучении Lua.
Lua за 60 минут(https://zserge.wordpress.com/2012/02/23/lua-за-60-минут/)

https://blast.hk/wiki/lua:requestmodel
Lua:
bool result = requestModel(Model model)
Можно составить большую таблицу (например weaponsmodel), где ключом будет ид оружия, а значением модель.
И в команде, перед выдачей делать так
Lua:
requestModel(weaponsmodel[wID])
Я тупой ? :mega_shok:
Lua:
require "lib.moonloader"
local weapons = require 'game.weapons'
    local weaponsmodel = {
  [0] = "Fist",
  [1] = "Brass Knuckles",
  [2] = "Golf Club",
  [3] = "Nightstick",
  [4] = "Knife",
  [5] = "Baseball Bat",
  [6] = "Shovel",
  [7] = "Pool Cue",
  [8] = "Katana",
  [9] = "Chainsaw",
  [10] = "Purple Dildo",
  [11] = "Dildo",
  [12] = "Vibrator",
  [13] = "Silver Vibrator",
  [14] = "Flowers",
  [15] = "Cane",
  [16] = "Grenade",
  [17] = "Tear Gas",
  [18] = "Molotov Cocktail",
  [22] = "9mm",
  [23] = "Silenced 9mm",
  [24] = "Desert Eagle",
  [25] = "Shotgun",
  [26] = "Sawnoff Shotgun",
  [27] = "Combat Shotgun",
  [28] = "Micro SMG/Uzi",
  [29] = "MP5",
  [30] = "AK-47",
  [31] = "M4",
  [32] = "Tec-9",
  [33] = "Country Rifle",
  [34] = "Sniper Rifle",
  [35] = "RPG",
  [36] = "HS Rocket",
  [37] = "Flamethrower",
  [38] = "Minigun",
  [39] = "Satchel Charge",
  [40] = "Detonator",
  [41] = "Spraycan",
  [42] = "Fire Extinguisher",
  [43] = "Camera",
  [44] = "Night Vis Goggles",
  [45] = "Thermal Goggles",
  [46] = "Parachute" }

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('gg', function(args)
    requestModel(weaponsmodel[wID])
    local wID = tonumber(args)
        if wID ~= nil then
            requestModel(weaponsmodel[wID])
            giveWeaponToChar(PLAYER_PED, wID, 100)
            sampAddChatMessage("You received weapon under " .. wID .. " ID",0x5A90CE)
        else
            sampAddChatMessage("Say ID weapon", 0x5A90CE)
        end
    end)
    wait(-1)
end
Я что-то упустил ? :sick:
 

Terratomorf

Известный
315
58
Один из вариантов, словить onCreatePickup и записывать все пикапы в массив. Затем перебрать массив на дистанцию, взять самый ближний и затем setCharCoordinates.


Lua:
local samp = require 'lib.samp.events'

function samp.onServerMessage(color, text)
    if text:find('Успех') then
        activation = false
    end
end

if activation then
    -- код
end
Что-то не так вставил?
Код:
local samp = require 'lib.samp.events'

function samp.onServerMessage(color, text)
    if text:find('Успешно') then
        activation = false
    end
end

if activation then
    require("lib.moonloader")

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        lua_thread.create(function()
            for i = 1000, 10000 do
                sampSendChat("/sur "..i)
                wait(50)
            end
        end)
    end)
    while true do
        wait(-1)
    end
end
end
 

Nishikinov

Известный
148
34
Что-то не так вставил?
Код:
local samp = require 'lib.samp.events'

function samp.onServerMessage(color, text)
    if text:find('Успешно') then
        activation = false
    end
end

if activation then
    require("lib.moonloader")

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        lua_thread.create(function()
            for i = 1000, 10000 do
                sampSendChat("/sur "..i)
                wait(50)
            end
        end)
    end)
    while true do
        wait(-1)
    end
end
end
Ты делаешь проверку слишком рано. Ее нужно вставлять непосредственно перед кодом, который ты не хочешь чтобы выполнялся.
Забыл сказать, присвой переменной true в начале скрипта, чтобы изначально действие выполнялось.
 

Terratomorf

Известный
315
58
Ты делаешь проверку слишком рано. Ее нужно вставлять непосредственно перед кодом, который ты не хочешь чтобы выполнялся.
Забыл сказать, присвой переменной true в начале скрипта, чтобы изначально действие выполнялось.
:thinking:Просто дай готовый не понимаю
 

Nishikinov

Известный
148
34
:thinking:Просто дай готовый не понимаю
На готовом не научишься.

Lua:
local samp = require 'lib.samp.events'
activation = true -- активируем изначально

function samp.onServerMessage(color, text)
    if text:find('Успешно') then
        activation = false -- при нахождении строки сбрасываем активацию
    end
end

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    sampRegisterChatCommand("start", function()
        lua_thread.create(function()
            while true do -- бесконечный цикл
                wait(0)
                if activation then -- если активация, значит выполняем до бесконечности
                -- при сбросе цикл будет продолжать работать, проверяя переменную.
                -- можешь затем снова присвоить ей true и далее выполнять действие пока не найдешь надпись, и так по кругу
                sampSendChat("/sur "..i)
                wait(50)
                end
            end
        end)
    end)
    wait(-1) -- либо сразу ставь wait(-1) либо делай while true do wait(0) end
end
 
  • Нравится
Реакции: Terratomorf

checkdasound

Известный
Проверенный
963
406

utmpL

Активный
309
65
Распишите в скрипте на выдачу розыска что где каво чаво и тд.
а тут даже пытаться не стоил или всё таки что-то.
Ток объясните как нубу (т.к. за луа не так давно взялся)
Lua:
function main()
    repeat wait(0) until isSampAvailable() -- проверка на то, что самп загружен
    sampRegisterChatCommand('pnanad', pnanad) -- регистрация команды
    repeat wait(0) until false -- бесконечный цикл
end

function pnanad(param)
pnanad = tonumber(param) -- переводим переменную param в pnanad только цифрами. если не только цифры, то выдаст nil
if param then -- если param был задействован (команда)
    if pnanad ~= nil then -- если pnanad не равен nil, тогда...(если nil выводить в чат, то крашит, как я знаю)
        sampSendChat('/su '..pnanad..' 6 Нападение на сотрудника ПО') -- пишем в чат
    end
end
end
 

Nishikinov

Известный
148
34
Распишите в скрипте на выдачу розыска что где каво чаво и тд.
а тут даже пытаться не стоил или всё таки что-то.
Ток объясните как нубу (т.к. за луа не так давно взялся)
Я хз откуда ты взял синтаксис, но это выглядит страшно.

Отправка:
Lua:
id = 1
sampSendChat("/su "..id.." 5 Нападение и бла-бла-бла")

Проверка:
Lua:
if id == 1 then -- пишем без кавычек, если тип числовой
end

Нормальная функция с параметрами:
Lua:
function myFunction(params)
   local id = tonumber(string.match(params, '(%d+)')) -- ищем только числа в строке параметров из чата + сразу приводим строку к числовому типу
-- или же local id, name = string.match(params, '(%d+) (.+)') -- ищем в формате число + строка через пробел, тогда приводить ид к числу нужно отдельно
   if id ~= nil then -- если ид не пустой
    -- наш код
  else
    sampAddChatMessage("Не введен ID игрока", 0xC1C1C1)
  end
 
  • Нравится
Реакции: atizoff

Howl1337

Известный
236
146
Тебе подобрать нужно или просто телепортироваться? Если тп, то просто находи координаты и телепортируйся.
А если подобрать, то отправляй синхру на координаты и уже sampSendPickedUpPickup, чтобы сервер думал, что ты стоишь на пикапе (код ниже).
Lua:
pickup_id = 322

-- function main while true do
local pickup = sampGetPickupHandleBySampId(pickup_id)
local pickup_x, pickup_y, pickup_z = getPickupCoordinates(pickup)
function sendOnfootSync(pickup_x, pickup_y, pickup_z)
sampSendPickedUpPickup(pickup_id)

function sendOnfootSync(x, y, z)
   local _, myId = sampGetPlayerIdByCharHandle(PLAYER_PED)
   local data = allocateMemory(68)
   sampStorePlayerOnfootData(myId, data)
   setStructFloatElement(data, 6, x, false)
   setStructFloatElement(data, 10, y, false)
   setStructFloatElement(data, 14, z, false)
   sampSendOnfootData(data)
   freeMemory(data)
end

Там они рандомно эти пикапы(лесопилка ДРП, дерево меняется), нужно телепортироваться, а не просто подобрать