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

Azller Lollison

я узбек
Друг
1,343
2,271
Здесь прикол в прошлом моём сообщении, разные высоты на поверхностях, а одним Y-ом не получишь точное понимание того, в воздухе ли транспорт или нет, только если костылить через зоны, но нафиг оно нужно?
Lua:
    float z = getGroundZFor3dCoord(float atX, float atY, float atZ)
 

Dmitriy Makarov

25.05.2021
Проверенный
2,480
1,113
можно сделать так чтобы больше 1 раза не выводился в чат ник одного и того же игрока за 1 заход в игру?
а то каждый раз одним и тем же ником флудит
Lua:
function main()
   
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(3500) end
   
    sampAddChatMessage("{FFFFFF}Какой-то скрипт загрузился.", 0xB45F04)
   
    while true do
        wait(0)
       
        local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE)
        if valid and doesCharExist(ped) then
            local result, id = sampGetPlayerIdByCharHandle(ped)
            if result and isKeyJustPressed(VK_LBUTTON) then
            local nick = sampGetPlayerNickname(id):gsub('_', '_')
            local _, id = sampGetPlayerIdByCharHandle(ped)
            sampAddChatMessage("{00FFFF}[Info] Ник пиздюка: "..nick.."["..id.."]", 0x00FFFF)
            end
        end
    end
end
 

Di3

Участник
432
20
Что лучше будет, ини или через json сохранять данные?


С ини при крашах, резком завершении гта сохраняет я пустой файл.
 

dmitri4

Известный
452
79
можно сделать так чтобы больше 1 раза не выводился в чат ник одного и того же игрока за 1 заход в игру?
а то каждый раз одним и тем же ником флудит
Полученный ник объявляешь глобальным и в дальнейшем сравниваешь его со следующим полученным ником
 

Azller Lollison

я узбек
Друг
1,343
2,271
шок, просто шок
Т.е. если оно >0 то это транспорт значит в воздухе?
Или иначе: как измеряется высота? От педа или от колёс?

если z кара > getGroundZFor3dCoord то в воздухе, отмеряется от центра кара вроде
 
  • Нравится
Реакции: ufard

Jason2222

Известный
180
3
Парни, нужна идея как это можно реализовать. У меня есть, допустим, диалоговое окно. В нем содержатся данные с подменюшками. И мне нужно, чтобы строки добавлялись в нем автоматически, если появится информация дополнительная при получении запроса с информацией. И чтобы эти подменюшки тоже добавлялись. Никак не могу допереть до этого. Может, я даже не очень доходчиво объяснил. Но надеюсь на помощь.
 

astynk

Известный
Проверенный
742
530
Как можно выровнять текст, пробовал \t но что то не сильно получилось
pPTmirF.png
Проблема в последнем параметре у sampShowDialog(). У тебя там стоит 2 (DIALOG_STYLE_LIST), а нужно 4 (DIALOG_STYLE_TABLIST).
 
  • Нравится
Реакции: dmitri4

Drinkins

Участник
38
0
Здравствуйте! Насколько я знаю, способ регистрации команд через sampRegisterChatCommand не самый лучший, подскажите пожалуйста, какие способы ещё есть? (желательно с примерами)
 

BRaze

Участник
84
0
Код замены текста чата в два цвета.
С: Nick_Name сказал: Привет.
На: Nick_Name сказал: Привет.
 
Последнее редактирование:

FBenz

Активный
328
40
  • Нравится
Реакции: WebDim

dmitri4

Известный
452
79
Здравствуйте! Насколько я знаю, способ регистрации команд через sampRegisterChatCommand не самый лучший, подскажите пожалуйста, какие способы ещё есть? (желательно с примерами)
То что все ещё существует ограничение в 144 команды было легендой от хомячка (вроде :) ), а так если хочешь через events можно
 

TheZoloman

Новичок
29
3
Код:
local sampev = require 'lib.samp.events'
local hook = require    'lib.samp.events'
local activate = true

local valid_car_for_tp = {409, 456, 349, 446, 452, 453, 454, 472, 473, 478, 484, 493, 554, 543, 595, 422, 605, 600, 567, 80, 86, 180, 186,}

function main()
  repeat wait(1) until isSampAvailable()
  sampAddChatMessage('Teleport Helper Loaded', -1)
  sampRegisterChatCommand("tph", TeleportHelper)

    while true do
    wait(0)
    end
    end

function TeleportHelper()
    for i = 0, 2000 do
    local res, veh = sampGetCarHandleBySampVehicleId()
    if res then
    local cx, cy, cz = getCarCoordinates(veh)
    if isCarModel(veh, valid_car_for_tp) then
    sampSendChat("/tpc " .. valid_car_for_tp)
    end
    end
    end
    end

    function FindVehicleForTp()
        local x, y, z = getCharCoordinates(PLAYER_PED)
        for i = 0, 2000 do
      local res, veh = sampGetCarHandleBySampVehicleId(i)
        if res then
        for j = 1, #valid_car_for_tp do
        if isCarModel(veh, valid_car_for_tp[j]) then
        return i
            end
            end
            end
            return -1
            end
            end


    local veh = FindVehicleForTp()
    if veh == -1 then return sampAddChatMessage('[Helper] Нет машины в стриме для телепорта, либо кар далеко', -1) end
    if isCharInAnyCar(PLAYER_PED) then return sampAddChatMessage('[helper] Телепорт работает только с ног', -1) end

Делаю простой скрипт
он должен писать /tpc и айди кара из списка при вводе комы /tph
но почему-то постоянно пишет что нет в зоне стрима кара

Код:
local sampev = require 'lib.samp.events'
local hook = require    'lib.samp.events'
local activate = true

local valid_car_for_tp = {409, 456, 349, 446, 452, 453, 454, 472, 473, 478, 484, 493, 554, 543, 595, 422, 605, 600, 567, 80, 86, 180, 186,}

function main()
  repeat wait(1) until isSampAvailable()
  sampAddChatMessage('Teleport Helper Loaded', -1)
  sampRegisterChatCommand("tph", TeleportHelper)

    while true do
    wait(0)
    end
    end

function TeleportHelper()
    for i = 0, 2000 do
    local res, veh = sampGetCarHandleBySampVehicleId()
    if res then
    local cx, cy, cz = getCarCoordinates(veh)
    if isCarModel(veh, valid_car_for_tp) then
    sampSendChat("/tpc " .. valid_car_for_tp)
    end
    end
    end
    end

    function FindVehicleForTp()
        local x, y, z = getCharCoordinates(PLAYER_PED)
        for i = 0, 2000 do
      local res, veh = sampGetCarHandleBySampVehicleId(i)
        if res then
        for j = 1, #valid_car_for_tp do
        if isCarModel(veh, valid_car_for_tp[j]) then
        return i
            end
            end
            end
            return -1
            end
            end


    local veh = FindVehicleForTp()
    if veh == -1 then return sampAddChatMessage('[Helper] Нет машины в стриме для телепорта, либо кар далеко', -1) end
    if isCharInAnyCar(PLAYER_PED) then return sampAddChatMessage('[helper] Телепорт работает только с ног', -1) end

Делаю простой скрипт
он должен писать /tpc и айди кара из списка при вводе комы /tph
но почему-то постоянно пишет что нет в зоне стрима кара,хотя я добавлял кары которые 100% были в стриме

Буду рад любому совету
 

dmitri4

Известный
452
79
Как после заполнения таблицы списком игроков функцией submenus_show сделать отдельные действия для каждого игрока, при нажатии на кого нибудь просто крашит скрипт
Lua:
local mod_submenus_sa = { 
    {
        title = 'Список',
        submenu = {},
        onclick = function(menu, row, submenu)
            table.insert(submenu, {title = table.concat(players)})
        end
    }
}