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

trefa

3d print
Всефорумный модератор
2,107
1,260
Lua:
function getPlayerSeatID(playerid)
    require 'samp.synchronization'
    local ffi = require 'ffi'--
    local data_type = 'struct PassengerSyncData'
    local data = ffi.new(data_type, {})
    local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
    sampStorePlayerPassengerData(playerid, raw_data_ptr)
return readMemory(raw_data_ptr + 2, 1, true)
end
Ругается на эту фигню, как пофиксить?
Код:
[19:42:10.159106] (error)    Spinfo: E:\arp\moonloader\lib\samp\synchronization.lua:154: attempt to redefine 'VectorXYZ' at line 2
stack traceback:
    [C]: in function 'cdef'
    E:\arp\moonloader\lib\samp\synchronization.lua:154: in main chunk
    [C]: in function 'require'
    E:\arp\moonloader\lib\samp\events\utils.lua:34: in function 'read_data'
    E:\arp\moonloader\lib\samp\events\core.lua:78: in function <E:\arp\moonloader\lib\samp\events\core.lua:54>
[19:42:10.169106] (error)    Spinfo: Script died due to an error. (21D47B24)
 

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
Lua:
function getPlayerSeatID(playerid)
    require 'samp.synchronization'
    local ffi = require 'ffi'--
    local data_type = 'struct PassengerSyncData'
    local data = ffi.new(data_type, {})
    local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
    sampStorePlayerPassengerData(playerid, raw_data_ptr)
return readMemory(raw_data_ptr + 2, 1, true)
end
Ругается на эту фигню, как пофиксить?
Код:
[19:42:10.159106] (error)    Spinfo: E:\arp\moonloader\lib\samp\synchronization.lua:154: attempt to redefine 'VectorXYZ' at line 2
stack traceback:
    [C]: in function 'cdef'
    E:\arp\moonloader\lib\samp\synchronization.lua:154: in main chunk
    [C]: in function 'require'
    E:\arp\moonloader\lib\samp\events\utils.lua:34: in function 'read_data'
    E:\arp\moonloader\lib\samp\events\core.lua:78: in function <E:\arp\moonloader\lib\samp\events\core.lua:54>
[19:42:10.169106] (error)    Spinfo: Script died due to an error. (21D47B24)
не вызывай samp.synchronization. если вызвал samp.events, то не вызывай samp.synchronization, если нет, то вызывай ОДИН раз.
 

trefa

3d print
Всефорумный модератор
2,107
1,260
не вызывай samp.synchronization. если вызвал samp.events, то не вызывай samp.synchronization, если нет, то вызывай ОДИН раз.
А как тогда можно узнать на каком месте в машине сидит игрок, если я юзаю samp.events и не могу использовать эту функцию (ибо краш)

Как можно нарисовать прямоугольник зависящий от длины текста?
 
Последнее редактирование модератором:

Frapsy

Известный
Проверенный
393
227
Lua:
local q = require 'lib.samp.events'

function main()
    repeat wait(0) until isSampAvailable()
    wait(-1)
end

function q.onBulletSync(playerId, data)
    if playerId == pID then
        sampAddChatMessage('Target '..data.targetId..' WeaponId '..data.weaponId..' tX '..data.target.x..' tY '..data.target.y..' tZ '..data.target.z, -1)
    end
end
--[[
struct BulletSyncData
{
    uint8_t               targetType;
    uint16_t           targetId;
    struct VectorXYZ origin;
    struct VectorXYZ target;
    struct VectorXYZ center;
    uint8_t               weaponId;
} __attribute__ ((packed));
]]

Спасибо, но в этом случае мы получаем цель, по которой стреляет заданный игрок и оружие, из которого идет стрельба(кулак не ловит), вопрос состоит в том, как получить инфу о дамаге, который указанный игрок нанес :c Все гуглю информацию по BulletSyncData, onBulletSync и что-то ничего :c
 

imring

Ride the Lightning
Всефорумный модератор
2,362
2,545
как получить сколько патронов не в обойме(выделено красным)

это не то:
Функция позволяет узнать сколько патронов в обойме.
Lua:
function getAmmoInClip()
  local struct = getCharPointer(playerPed)
  local prisv = struct + 0x0718
  local prisv = memory.getint8(prisv, false)
  local prisv = prisv * 0x1C
  local prisv2 = struct + 0x5A0
  local prisv2 = prisv2 + prisv
  local prisv2 = prisv2 + 0x8
  local ammo = memory.getint32(prisv2, false)
  return ammo
end
Использование:
local ammoinclip = getAmmoInClip()
P.S.
Lua:
local memory = require "memory"
в начало кода пропишите.
int ammo = getAmmoInCharWeapon(Ped ped, int int)
[TBODY] [/TBODY]
от всего количества патрон отними кол-во патрон в обойме.
 
  • Нравится
Реакции: #kerosin

штейн

Известный
Проверенный
1,003
688
приветик помогите))))

Lua:
    function sampev.onServerMessage(color, text)
      if text:find('Деньги перечислены на ваш банковский счёт.') then
        local screen = text:match('Деньги перечислены на ваш банковский счёт.')
      if screen then
                sampAddChatMessage("[ {800000}HitMan {ffffff}]: Контракт выполнен! {800000}Hitman Help {ffffff}автоматически сделает скриншот.", -1)
                screenshot()
                if data.options.screenshot == 1 then wait(750) end
                if data.options.screenshot == 0 then wait(1200) end
        end
      end
    end

как сделать так, чтобы "Деньги перечислены на ваш банковский счёт." не писалось в чат? т.е. типо сервер отправляет мне это сообщение в чат, но скрипт его читает и удаляет т.е. я его не вижу
 

Alkasch226

Известный
43
4
приветик помогите))))

Lua:
    function sampev.onServerMessage(color, text)
      if text:find('Деньги перечислены на ваш банковский счёт.') then
        local screen = text:match('Деньги перечислены на ваш банковский счёт.')
      if screen then
                sampAddChatMessage("[ {800000}HitMan {ffffff}]: Контракт выполнен! {800000}Hitman Help {ffffff}автоматически сделает скриншот.", -1)
                screenshot()
                if data.options.screenshot == 1 then wait(750) end
                if data.options.screenshot == 0 then wait(1200) end
        end
      end
    end

как сделать так, чтобы "Деньги перечислены на ваш банковский счёт." не писалось в чат? т.е. типо сервер отправляет мне это сообщение в чат, но скрипт его читает и удаляет т.е. я его не вижу
После
Lua:
if text:find('Деньги перечислены на ваш банковский счёт.') then
Поставь
Lua:
return false
 

штейн

Известный
Проверенный
1,003
688
После
Lua:
if text:find('Деньги перечислены на ваш банковский счёт.') then
Поставь
Lua:
return false
если вставляю пишет после local end поставить, но это типа бред же да

всё сделал, только return false поставил в самый конец функции.
 
Последнее редактирование модератором:

ШPEK

Известный
1,474
525
Lua:
script_name("Restore health")
script_author("noname_noob")
require "lib.moonloader"

function main()
while not isSampAvailable() do wait(100) end
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while true do
    wait(0)
         if getCurrentCharWeapon(playerPed) == 24 then
            sampAddChatMessage("dailog", FFFFFF) wait(1)
         end
    end
end
планировалось чтобы писало dailog 1 раз, а он флудит. Как исправить?
 

штейн

Известный
Проверенный
1,003
688
Lua:
script_name("Restore health")
script_author("noname_noob")
require "lib.moonloader"

function main()
while not isSampAvailable() do wait(100) end
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while true do
    wait(0)
         if getCurrentCharWeapon(playerPed) == 24 then
            sampAddChatMessage("dailog", FFFFFF) wait(1)
         end
    end
end
планировалось чтобы писало dailog 1 раз, а он флудит. Как исправить?

я обычно в таких случаях ставлю wait(1000), мне помогает, хотя мне кажется так делают только быдло-кодеры (как я)
 

ШPEK

Известный
1,474
525
Как сделать авторп отыгровку оружия? Пытался, получилось Г.
Код:
script_name("Restore health")
script_author("noname_noob")
require "lib.moonloader"

function main()
while not isSampAvailable() do wait(100) end
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    while true do
    wait(0)
         if getCurrentCharWeapon(playerPed) == 24 then
            sampAddChatMessage("dailog", FFFFFF) wait(1)
         end
    end
end