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

shizzard

Участник
150
7
как сделать таймер который будет отсчитывать время в имгуи меню и таймер который будет отситывать время на самом экране?
все время,даже если игра свернута
 

CaJlaT

07.11.2024 14:55
Модератор
2,830
2,660
как получить значение из слайдер инт?
Lua:
local slider = imgui.ImInt(0)


--onDrawFrame
imgui.SliderInt(u8"Слайдер", slider, 0--[[минимальное число]], 100--[[максимальное число]])


--там, где нужно получить значение слайдера
slider.v
как сделать таймер который будет отсчитывать время в имгуи меню и таймер который будет отситывать время на самом экране?
все время,даже если игра свернута
Как и просил в вк, активация по imgui.Button, а настройка через слайдер
Lua:
local min = imgui.ImInt(10)
local timer = 0


--onDrawFrame
imgui.SliderInt(u8"Таймер (минуты)", slider, 10--[[минимальное число]], 20--[[максимальное число]])
if imgui.Button(u8'Начать отсчёт') then
    if timer < os.time() then -- если таймер не идёт (меньше, чем время на пк)
        timer = os.time() + (min.v * 60) -- время на пк(в секундах) + перевод значения слайдера в минуты
    else -- если таймер больше, чем время на пк (если идёт)
        sampAddChatMessage('Ошибка, отсчёт уже идёт!', -1)
    end
end
if timer >= os.time() then -- пока таймер больше времени на пк (пока он идёт)
    imgui.Text(math.floor((timer - os.time())/60)..':'..math.floor((timer - os.time())%60))
    --math.floor для того, чтобы после деления выводило целое число
    --(timer - os.time())/60) -- ((таймер-время на пк/)1 минуту) для определения минут
    --(timer - os.time())%60) -- остаток деления на 60 (секунды)
end
 
Последнее редактирование:
  • Нравится
Реакции: shizzard

Dashok.

Участник
228
9
Как сделать так что-бы при зажатии на игрока Правой кнопкой мыши, и нажатии на R, открывалось имгуи окно
 

NECTOR

Известный
33
13
Всем привет. Хочу узнать, каким образом можно в зоне стрима ( или определённого расстояния) проверять, если разность между мной и игроком по z > значения?
 

samartinell1

Участник
98
14
Lua:
      imgui.BeginChild('##5',imgui.ImVec2(285,510),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n\t'..os.date('%H:%M'))
      imgui.SameLine()
      imgui.Text('\t ')
      imgui.SameLine()
      imgui.Image(texture_cringe, imgui.ImVec2(157,25))
      imgui.SameLine()
      imgui.Text('\n'..fa.ICON_SIGNAL..' '..fa.ICON_WIFI..' '..fa.ICON_BATTERY_FULL)
      imgui.BeginChild('Messages', imgui.ImVec2(285,480),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n')
      imgui.TextColoredRGB('\t{000000} Messages')
      imgui.Text('\t\t\t')
      imgui.SameLine()
      imgui.InputText(fa.ICON_SEARCH, buffersearch)
      imgui.Separator()
      smstexttoimgui = ''
      local file = io.open(getWorkingDirectory().."/phone interface/sms.txt")
      for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        smsltime, smslcount, smslnumber, smslnick, smsltext = line:match('(%d+:%d+) | (%d+) | (%d+) | (.+_.+) | (.+)')
        statesms = '{000000}'..smslnick..'\t('..smsltime..')'..'\n\t\t\t'..smsltext..'\n'
        smstexttoimgui = smstexttoimgui..statesms
      end
      if smslnick == nil then
        imgui.Text('\n\n\n\t\t\t\t\t\t\t\t\tNone')
      elseif smslnick ~= nil and smsltext ~= nil and smslnumber ~= nil and smsltime ~= nil then
        if string.find(smslnick, buffersearch.v) then
          imgui.Text(buffersearch.v)
        end
        for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        imgui.Button(fa.ICON_ENVELOPE, imgui.ImVec2(30,30))
        imgui.SameLine()
          imgui.TextColoredRGB(u8(smstexttoimgui))
          imgui.Separator()
        end
        file:close()
      end

Как сделать так, чтобы каждое сообщение было в отдельной переменной, smslcount - это порядковое число сообщений, то есть каждое новое сообщение со своим номером. Как из smstexttoimgui сделать таблицу или хоть что то, чтобы у каждой строки в файлике была своя переменная и это работало автоматически(ну чтобы ограничений по строкам не было). Спасибо!
Как сделать так что-бы при зажатии на игрока Правой кнопкой мыши, и нажатии на R, открывалось имгуи окно
Lua:
    if getCharPlayerIsTargeting() == true and isKeyJustPressed(VK_R) then
      local result, target = getCharPlayerIsTargeting(playerHandle)
      if result then result, targetid = sampGetPlayerIdByCharHandle(target) end
      if sampIsPlayerConnected(targetid) then
      kakoe_to_window.v = true
    end
    end
закинь это всё в беск цикл и как бы всё. targetid - айди игрока которого ты затаргетил
 
Последнее редактирование:

Dashok.

Участник
228
9
Lua:
      imgui.BeginChild('##5',imgui.ImVec2(285,510),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n\t'..os.date('%H:%M'))
      imgui.SameLine()
      imgui.Text('\t ')
      imgui.SameLine()
      imgui.Image(texture_cringe, imgui.ImVec2(157,25))
      imgui.SameLine()
      imgui.Text('\n'..fa.ICON_SIGNAL..' '..fa.ICON_WIFI..' '..fa.ICON_BATTERY_FULL)
      imgui.BeginChild('Messages', imgui.ImVec2(285,480),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n')
      imgui.TextColoredRGB('\t{000000} Messages')
      imgui.Text('\t\t\t')
      imgui.SameLine()
      imgui.InputText(fa.ICON_SEARCH, buffersearch)
      imgui.Separator()
      smstexttoimgui = ''
      local file = io.open(getWorkingDirectory().."/phone interface/sms.txt")
      for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        smsltime, smslcount, smslnumber, smslnick, smsltext = line:match('(%d+:%d+) | (%d+) | (%d+) | (.+_.+) | (.+)')
        statesms = '{000000}'..smslnick..'\t('..smsltime..')'..'\n\t\t\t'..smsltext..'\n'
        smstexttoimgui = smstexttoimgui..statesms
      end
      if smslnick == nil then
        imgui.Text('\n\n\n\t\t\t\t\t\t\t\t\tNone')
      elseif smslnick ~= nil and smsltext ~= nil and smslnumber ~= nil and smsltime ~= nil then
        if string.find(smslnick, buffersearch.v) then
          imgui.Text(buffersearch.v)
        end
        for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        imgui.Button(fa.ICON_ENVELOPE, imgui.ImVec2(30,30))
        imgui.SameLine()
          imgui.TextColoredRGB(u8(smstexttoimgui))
          imgui.Separator()
        end
        file:close()
      end

Как сделать так, чтобы каждое сообщение было в отдельной переменной, smslcount - это порядковое число сообщений, то есть каждое новое сообщение со своим номером. Как из smstexttoimgui сделать таблицу или хоть что то, чтобы у каждой строки в файлике была своя переменная и это работало автоматически(ну чтобы ограничений по строкам не было). Спасибо!

Lua:
    if getCharPlayerIsTargeting() == true and isKeyJustPressed(VK_R) then
      local result, target = getCharPlayerIsTargeting(playerHandle)
      if result then result, targetid = sampGetPlayerIdByCharHandle(target) end
      if sampIsPlayerConnected(targetid) then
      kakoe_to_window.v = true
    end
    end
закинь это всё в беск цикл и как бы всё. targetid - айди игрока которого ты затаргетил
Не работает .-.
 
У

Удалённый пользователь 341712

Гость
и не будет
Lua:
result, handle = getCharPlayerIsTargeting(playerHandle)
if result then
    if isKeyJustPressed(VK_R) then
        window.v = not window.v
    end
end
Lua:
      imgui.BeginChild('##5',imgui.ImVec2(285,510),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n\t'..os.date('%H:%M'))
      imgui.SameLine()
      imgui.Text('\t ')
      imgui.SameLine()
      imgui.Image(texture_cringe, imgui.ImVec2(157,25))
      imgui.SameLine()
      imgui.Text('\n'..fa.ICON_SIGNAL..' '..fa.ICON_WIFI..' '..fa.ICON_BATTERY_FULL)
      imgui.BeginChild('Messages', imgui.ImVec2(285,480),nil, imgui.WindowFlags.NoScrollbar)
      imgui.Text('\n')
      imgui.TextColoredRGB('\t{000000} Messages')
      imgui.Text('\t\t\t')
      imgui.SameLine()
      imgui.InputText(fa.ICON_SEARCH, buffersearch)
      imgui.Separator()
      smstexttoimgui = ''
      local file = io.open(getWorkingDirectory().."/phone interface/sms.txt")
      for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        smsltime, smslcount, smslnumber, smslnick, smsltext = line:match('(%d+:%d+) | (%d+) | (%d+) | (.+_.+) | (.+)')
        statesms = '{000000}'..smslnick..'\t('..smsltime..')'..'\n\t\t\t'..smsltext..'\n'
        smstexttoimgui = smstexttoimgui..statesms
      end
      if smslnick == nil then
        imgui.Text('\n\n\n\t\t\t\t\t\t\t\t\tNone')
      elseif smslnick ~= nil and smsltext ~= nil and smslnumber ~= nil and smsltime ~= nil then
        if string.find(smslnick, buffersearch.v) then
          imgui.Text(buffersearch.v)
        end
        for line in io.lines(getWorkingDirectory().."/phone interface/sms.txt") do
        imgui.Button(fa.ICON_ENVELOPE, imgui.ImVec2(30,30))
        imgui.SameLine()
          imgui.TextColoredRGB(u8(smstexttoimgui))
          imgui.Separator()
        end
        file:close()
      end

Как сделать так, чтобы каждое сообщение было в отдельной переменной, smslcount - это порядковое число сообщений, то есть каждое новое сообщение со своим номером. Как из smstexttoimgui сделать таблицу или хоть что то, чтобы у каждой строки в файлике была своя переменная и это работало автоматически(ну чтобы ограничений по строкам не было). Спасибо!

Lua:
    if getCharPlayerIsTargeting() == true and isKeyJustPressed(VK_R) then
      local result, target = getCharPlayerIsTargeting(playerHandle)
      if result then result, targetid = sampGetPlayerIdByCharHandle(target) end
      if sampIsPlayerConnected(targetid) then
      kakoe_to_window.v = true
    end
    end
закинь это всё в беск цикл и как бы всё. targetid - айди игрока которого ты затаргетил
Зачем проверять на это " if getCharPlayerIsTargeting() == true and isKeyJustPressed(VK_R) then", если оно только ломает скрипт? Зачет проверять на то что подключен игрок, если мой перс как то целится же
 

samartinell1

Участник
98
14
и не будет
Lua:
result, handle = getCharPlayerIsTargeting(playerHandle)
if result then
    if isKeyJustPressed(VK_R) then
        window.v = not window.v
    end
end

Зачем проверять на это " if getCharPlayerIsTargeting() == true and isKeyJustPressed(VK_R) then", если оно только ломает скрипт? Зачет проверять на то что подключен игрок, если мой перс как то целится же
проверка на подключенного игрока нужна, чтобы скрипт банально не крашнул при таргетинге на бота, каким образом первая строчка ломает скрипт, если она производит простую проверку на целится ли игрок на другого и нажал ли этот игрок клавишу. Да, наверное getCharPlayerTargeting() == true лишнее, так как это проверяется снова ниже, но это не так и существенно, я сам пользуюсь этим и у меня как то ничего не ломается, микрофризов и тд нет.
Да, твой вариант немного оптимизированнее, но в моём случае самп не крашнется при прицеливании на какого нить квестового персонажа на сервере :)
 
У

Удалённый пользователь 341712

Гость
проверка на подключенного игрока нужна, чтобы скрипт банально не крашнул при таргетинге на бота, каким образом первая строчка ломает скрипт, если она производит простую проверку на целится ли игрок на другого и нажал ли этот игрок клавишу. Да, наверное getCharPlayerTargeting() == true лишнее, так как это проверяется снова ниже, но это не так и существенно, я сам пользуюсь этим и у меня как то ничего не ломается, микрофризов и тд нет.
Бред
 

samartinell1

Участник
98
14
Я тестировал лично и дописывал проверку на находится ли игрок на сервере после нескольких крашей из-за того что целился на бота и нажимал клавишу R. Конечно мало кто будет бегать к ботам и пытаться активировать окно на нём, но всё же.
Только вспомнил, что краши происходили не из-за проверки, а из-за последующего взаимодействия с этими данными (айди игрока, ник и тд) в окне imgui, так что если взаимодействия не требуется, то и проверки лишней делать не нужно.
 
У

Удалённый пользователь 341712

Гость
Я тестировал лично и дописывал проверку на находится ли игрок на сервере после нескольких крашей из-за того что целился на бота и нажимал клавишу R. Конечно мало кто будет бегать к ботам и пытаться активировать окно на нём, но всё же.
Только вспомнил, что краши происходили не из-за проверки, а из-за последующего взаимодействия с этими данными (айди игрока, ник и тд) в окне imgui, так что если взаимодействия не требуется, то и проверки лишней делать не нужно.
А смысл мне к примеру целиться в бота? Если его не существует, даже если и так, то проблемы в коде, каждый бот под ИД сделан.
 
  • Нравится
Реакции: samartinell1

samartinell1

Участник
98
14
А смысл мне к примеру целиться в бота? Если его не существует, даже если и так, то проблемы в коде, каждый бот под ИД сделан.
Да, я ща посмотрел как я использую айди в имгуи том, я в названии указываю ник игрока и айдишник в которого целился, в таком случае при активации на бота крашит. Приношу глубоководные извинения, при простом использовании ничего крашить не будет. Ну опять же, если нужно взаимодействовать с игроком, то лучше обезопасить себя парой строчек кода (миссклик никто не отменял по боту, который рядом с игроком) и потом не парится, но в общем да, признаю ошибку :)