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

osminog

Новичок
87
14
Как сделать чтобы машина под текстуры по нажатию клавиши проваливалась?
 

Musaigen

abobusnik
Проверенный
1,586
1,314
Как сделать чтобы машина под текстуры по нажатию клавиши проваливалась?
проверяешь нажатие клавиши, далее получаешь Z координату земли функцией getGroundZFor3dCoord(float atX, float atY, float atZ) и потом просто setCarCoordinates
 

Belo4ka_belka

Известный
191
7
Здравствуйте. Имеется окно imgui с флагом 64 и заданными лимитами командой SetNextWindowSizeConstraints. Задача: создавать окно по центру экрана. Именно чтобы центр окна находился в центре, а не левый верхний угол. Команда SetNextWindowPos мне не помогла, пришлось использовать SetWindowPos после begin (т.к. напоминаю размер окна мне не известен в момент его создания). Я ещё могу смириться с тем, что окно телепортируется на втором кадре, т.к. в начале оно создается хрен пойми где, а уже на втором кадре идёт просчет высоты ширины и все красиво центрируется, но это работает так только если окно создается впервые или же вновь созданное окно больше предыдущего (текста побольше и т.д.), если же меньше окно то происходит очень плавное изменение размера окна с предыдущего большого до текущего маленького что уже ни в какие рамки. Вторая проблема: высчитал координаты положения кнопки (по центру по оси X и на 30 пикселей выше нижней границы окна), однако столкнулся с проблемой если текста много и появляется скрол то кнопка статично находится на своем месте над текстовым элементом и прокручивается вместе со скроллом соответственно, скрин: https://prnt.sc/n613f1. Собственно вопрос:
1) Можно ли как-нибудь высчитать координаты для кнопки с учетом скролла?
2) Можно ли просчитать ширину и высоту окна которое будет вот-вот создано (чтобы применить SetNextWindowPos корректно), или же просто задать параметр который зацентрирует следующее созданное окно (но применение флага 64 обязательно для меня) или избавится от телепортации в случае увеличения размера (не так критично) и от плааааавного-плавного уменьшения (в случае уменьшения размера окна)?

КОд:
Код:
function imgui.OnDrawFrame()
    if show_main_window.v and MainIni.Status.Read == "READ" then
        isCorrectClose = false
        sw, sh = getScreenResolution()
        imgui.SetNextWindowSizeConstraints(imgui.ImVec2(300, 200), imgui.ImVec2(sw / 2, sh / 2))
        imgui.Begin(u8(MainIni.Require.Title), show_main_window, 4 + 2 + 256 + 64)
        imgui.SetWindowPos(imgui.ImVec2(sw / 2 - imgui.GetWindowWidth() / 2, sh / 2 - imgui.GetWindowHeight() / 2), imgui.Cond.Always)
        imgui.ShowCursor = true
        textGui = MainIni.Require.Text:gsub("<e>", "\n")
        imgui.Text(u8(textGui))
        imgui.PushItemWidth(-1.0)
        imgui.InputText(u8'', moonimgui_text_buffer)
        imgui.PopItemWidth()
        if IsAppear then
            imgui.SetKeyboardFocusHere(-1)
            IsAppear = false
        end
        imgui.NewLine()
        imgui.NewLine()
        imgui.PushItemWidth(50.0)
        imgui.SetCursorPos(imgui.ImVec2(imgui.GetWindowWidth() / 2 - 50.0, imgui.GetWindowHeight() - 30))
        if imgui.Button(u8(MainIni.Require.ButtonText)) then
            isCorrectClose = true
            show_main_window.v = false
        end
        imgui.End()
    end
end

Просьба: если вы захотите просто ткнуть меня носом в функцию то хотя бы объясните что она возвращает, а то английский не самая сильная моя сторона. Хотя я и прошерстил список функций в скрипте я не нашел явного ответа. Рассчитываю на вашу помощь.

P.S. Вспомнил про одну малозначительную неприятность еще для меня: можно ли избавиться от стрелки в левом верхнем углу окна чтобы нельзя было его свернуть?
 
Последнее редактирование:

Musaigen

abobusnik
Проверенный
1,586
1,314
А что ты сможешь сделать без кода?
Вики же вроде ещё не забанили.

Задача: создавать окно по центру экрана.
imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
P.S. Вспомнил про одну малозначительную неприятность еще для меня: можно ли избавиться от стрелки в левом верхнем углу окна чтобы нельзя было его свернуть?
imgui.WindowFlags.NoCollapse
2) Можно ли просчитать ширину и высоту окна которое будет вот-вот создано (чтобы применить SetNextWindowPos корректно), или же просто задать параметр который зацентрирует следующее созданное окно (но применение флага 64 обязательно для меня) или избавится от телепортации в случае увеличения размера (не так критично) и от плааааавного-плавного уменьшения (в случае уменьшения размера окна)?
Можно спокойно использовать imgui.SetNextWindowSize(imgui.ImVec2(228, 1337), imgui.Cond.FirstUseEver) на работу флага AlwaysAutoResize это не повлияет
1) Можно ли как-нибудь высчитать координаты для кнопки с учетом скролла?
А куда собственно нужно центрировать кнопку?
Если в центр, то https://blast.hk/threads/19292/page-18#post-218877
лучше '##empty_field'
 
  • Нравится
Реакции: Belo4ka_belka

ШPEK

Известный
1,476
525
Как сделать вывод ида по таргету?
Lua:
local valid, ped = getCharPlayerIsTargeting(PLAYER_HANDLE) -- получить хендл персонажа, в которого целится игрок
if valid and doesCharExist(ped) then -- если цель есть и персонаж существует
  local result, id = sampGetPlayerIdByCharHandle(ped) -- получить samp-ид игрока по хендлу персонажа
  if result then -- проверить, прошло ли получение ида успешно
    sampAddChatMessage(id, -1)
  end
end
 
  • Нравится
Реакции: r4nx

Kuharz

Известный
407
154
Нужно сделать так, чтобы скрипт брал ид из строки выводимой другим скриптом "[21:52:15] [mkrn wrn]:{ffffff} Nick_Name[381] возможно сбив анимки машиной" и при нажатии кнопки отправлял строку /report id сбив
Пробовал через text match and text find, не работает.
 

Belo4ka_belka

Известный
191
7
Можно спокойно использовать imgui.SetNextWindowSize(imgui.ImVec2(228, 1337), imgui.Cond.FirstUseEver) на работу флага AlwaysAutoResize это не повлияет
Боюсь что это мне не подойдет. Мне не нужно окно в котором одна пустота только лишь из-за того что в этот раз я решил не 500 строк в текст вбить а 2 всего. Флаг 64 подгоняет окно под размер текста в пределах лимита SetNextWindowSizeConstraints. Или я неправильно рассуждаю?
imgui.SetNextWindowPos(imgui.ImVec2(sw / 2, sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
Я уже пробовал это. Вот где создается окно: http://prntscr.com/n61tbh.
А куда собственно нужно центрировать кнопку?
По оси Х центрировать я смог уже. Проблема в том, чтобы кнопка создавалась на 30 пикселей выше нижней границы окна но таким образом, чтобы если текст объемный и imgui создает скролл для его проматывания то кнопка была в самом низу после скролла, а не прокручивалась вместе со скроллом (сравните этот скриншот: https://prnt.sc/n613f1 с тем что я привел пару строчек выше (наглядно видно смещение кнопки вместе со скроллом), а теперь с тем, где кнопка должна находиться: http://prntscr.com/n61w1q). По остальным советам спасибо, учту.