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

Hatemaker

Известный
23
6
Есть готовый skybox.
В начале скрипта задаются временные данные, когда идёт переключение между разными скайбоксами (iDawn = 7; iDusk = 20). Необходимо, чтобы все скайбоксы отключались в 06:00 и в 21:00 (по игровому времени) и было чистое небо без звёзд и облаков. Что необходимо дописать/добавить, чтобы реализовать подобное?
 

Вложения

  • BetterSkybox.lua
    11.2 KB · Просмотры: 7

Hatiko

Известный
Проверенный
1,472
611
Кнопки можно и нужно использовать как условие в if
Lua:
if imgui.Button("Кнопка 1", imgui.ImVec2(200, 20)) then
--код, исполняющийся после нажатия кнопки
end
Lua:
imgui.Columns(count, id, border) -- - создает count колонок, которыми можно управлять с помощью функций:
Lua:
imgui.NextColumn() -- переводит "курсор" в следующую колонку
imgui.GetColumnIndex() -- возвращает номер текущей колонки
imgui.SetColumnWidth(index, width) -- задает ширину width колонки под номером index(-1 для текущей),
Это не все функции, но самые основные которые точно пригодятся.
Спасибо, разобрался с колонами, но не разобрался с кнопками.
Мне именно надо, чтобы при нажатии на Кнопку 1 было так, а при нажатии Кнопки 2 - так. Ну типо меню окна.
Основное окно:
Lua:
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if main_window_state.v then
    local sw, sh = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(430, 300), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin('Тестовое окно', main_window_state)
    imgui.Button("Кнопка 1", imgui.ImVec2(200, 20))
    imgui.Button("Кнопка 2", imgui.ImVec2(200, 20), imgui.SameLine())
    imgui.Separator()
    imgui.End()
    end
end
Кнопка 1:
Lua:
    imgui.Text("Text, text/////////")
    imgui.Text("Text 2")
    imgui.Text("Text 3")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")

Кнопка 2:
Lua:
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Separator()
    imgui.Text("Text, text/////////")
    imgui.Text("Text 2")
    imgui.Text("Text 3")
 

Vlad Horii

Известный
Проверенный
310
171
Спасибо, разобрался с колонами, но не разобрался с кнопками.
Мне именно надо, чтобы при нажатии на Кнопку 1 было так, а при нажатии Кнопки 2 - так. Ну типо меню окна.
Основное окно:
Lua:
local main_window_state = imgui.ImBool(false)
function imgui.OnDrawFrame()
  if main_window_state.v then
    local sw, sh = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(430, 300), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin('Тестовое окно', main_window_state)
    imgui.Button("Кнопка 1", imgui.ImVec2(200, 20))
    imgui.Button("Кнопка 2", imgui.ImVec2(200, 20), imgui.SameLine())
    imgui.Separator()
    imgui.End()
    end
end
Кнопка 1:
Lua:
    imgui.Text("Text, text/////////")
    imgui.Text("Text 2")
    imgui.Text("Text 3")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")

Кнопка 2:
Lua:
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Button("Кнопки"); imgui.SameLine()
    imgui.Button("Кнопки")
    imgui.Separator()
    imgui.Text("Text, text/////////")
    imgui.Text("Text 2")
    imgui.Text("Text 3")
Lua:
    if imgui.Button("Кнопка 1", imgui.ImVec2(200, 20)) then
        -- код для первой кнопки
    end
    if imgui.Button("Кнопка 2", imgui.ImVec2(200, 20), imgui.SameLine()) then
        -- код для второй кнопки
    end
 

ufdhbi

Известный
Проверенный
1,455
861
Как в луа посчитать какой элемент таблицы повторялся и сколько раз
количество дубликатов
в таблице найти
тип t = {"a","a","a","a","a","a","b","b"}
print(dub(t) )
a:6 b:2
 

Hatiko

Известный
Проверенный
1,472
611
Lua:
    if imgui.Button("Кнопка 1", imgui.ImVec2(200, 20)) then
        -- код для первой кнопки
    end
    if imgui.Button("Кнопка 2", imgui.ImVec2(200, 20), imgui.SameLine()) then
        -- код для второй кнопки
    end
Спасибо, оно работает, но не так как надо. Выводится текст и кнопки на долю секунды, как нажмёшь. А как сделать, чтобы было статически, нажал - появилось и не исчезало?
 

Dark_Knight

Me, me and me.
Друг
4,062
2,077
Проверку на бул переменную. Если переменная ХЕР равна истинне, то рисовать "кнопка 2", "Кнопка 3". Если нажата "Кнопка 1", то хер равен истине.
 
  • Нравится
Реакции: LaRossa

RTD

Нестандартное звание
Модератор
391
414
Как в луа посчитать какой элемент таблицы повторялся и сколько раз
количество дубликатов
в таблице найти
тип t = {"a","a","a","a","a","a","b","b"}
print(dub(t) )
a:6 b:2
Как вариант. Возможно есть лучше способы.
Lua:
local t = {"a","a","a","a","a","a","b","b"}
    local t2 = {}
    for _,e in ipairs(t) do
        if e == last_e then
            t2[e] = t2[e] ~= nil and t2[e] + 1 or 1
        end
        last_e = e
    end
    for i,e in pairs(t2) do
        sampAddChatMessage(i .. " | " .. e, -1)
    end
 

ufdhbi

Известный
Проверенный
1,455
861
Как вариант. Возможно есть лучше способы.
Lua:
local t = {"a","a","a","a","a","a","b","b"}
    local t2 = {}
    for _,e in ipairs(t) do
        if e == last_e then
            t2[e] = t2[e] ~= nil and t2[e] + 1 or 1
        end
        last_e = e
    end
    for i,e in pairs(t2) do
        sampAddChatMessage(i .. " | " .. e, -1)
    end
А если в тебдице не подряд идут а и б
 

AnWu

Guardian of Order
Всефорумный модератор
4,686
5,166
А если в тебдице не подряд идут а и б
Создай локальную таблу счетчика.
Lua:
local count = {}
-- Добавляй + 1 каждый раз по ключу-значению
count[e] = count[e] == nil 1 or count[e]  + 1
Перебор:
Lua:
for k, v in pairs(count) do
sampAddChatMessage(k .. " = " .. v, -1)
end
 

Hatiko

Известный
Проверенный
1,472
611
Проверку на бул переменную. Если переменная ХЕР равна истинне, то рисовать "кнопка 2", "Кнопка 3". Если нажата "Кнопка 1", то хер равен истине.
Что-то не получается, пробую по разному всегда ошибки разные вылетают. В этом коде вообще игра вылетела с объявлением ошибки.
Lua:
function imgui.OnDrawFrame()
  if main_window_state.v then
    local sw, sh = getScreenResolution()
    local text = true
    imgui.SetNextWindowSize(imgui.ImVec2(430, 300), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin('Тестовое окно', main_window_state)
    if imgui.Button("Кнопка 1", imgui.ImVec2(200, 20)) then
    local her = true
    end
    if her == true then
    imgui.Text("prov")
    end
end
end
 

Dark_Knight

Me, me and me.
Друг
4,062
2,077
Не правильно обьявил. Там где ты её проверяешь её не существует.
 

AnWu

Guardian of Order
Всефорумный модератор
4,686
5,166
Не правильно обьявил. Там где ты её проверяешь её не существует.
Он забыл imgui.End() в конце)
Lua:
function imgui.OnDrawFrame()
  if main_window_state.v then
    local sw, sh = getScreenResolution()
    local text = true
    imgui.SetNextWindowSize(imgui.ImVec2(430, 300), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin('Тестовое окно', main_window_state)
    if imgui.Button("Кнопка 1", imgui.ImVec2(200, 20)) then
         imgui.Text("prov")
    end
    imgui.End()
end
end
 

Hatiko

Известный
Проверенный
1,472
611
Все равно что-то не работает, поставил в конце условия кнопки return her, крашнуло игру.