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

Setkh

Участник
74
6
Как получить ник в формате: W_Setkh (первая буква имени, и полностью фамилия), но при этом переменная nick все равно должна содержать полный ник, в ней может быть и "123nickname_"

Lua:
if text:find("%[Жалоба%] .+%[%d+%]: {FFFFFF}%d+ .+") then
    nick, idpm, idre, sup = text:match("%[Жалоба%] (.+)%[(%d+)%]: {FFFFFF}(%d+) (.+)")
    sampAddChat(" /mute "..idre.." 20 Reason | "..nick) --Тут в nick должно быть сокращенное: W_Setkh
end
 

Izvinisb

Известный
Проверенный
963
600
Как получить ник в формате: W_Setkh (первая буква имени, и полностью фамилия), но при этом переменная nick все равно должна содержать полный ник, в ней может быть и "123nickname_"

Lua:
if text:find("%[Жалоба%] .+%[%d+%]: {FFFFFF}%d+ .+") then
    nick, idpm, idre, sup = text:match("%[Жалоба%] (.+)%[(%d+)%]: {FFFFFF}(%d+) (.+)")
    sampAddChat(" /mute "..idre.." 20 Reason | "..nick) --Тут в nick должно быть сокращенное: W_Setkh
end
text:gsub() и sampAddChatMessage()
 

Quasper

Известный
835
354
Допустим ид диалога 228 , а на кнопке надпись "выбрать " че делать ? По синтаксису не понял прост
Допустим ид диалога 228 , а на кнопке надпись "выбрать " че делать ? По синтаксису не понял прост
sampSendDialogResponse(228, 1, nil, nil)
1) 228 - ид диалога
2) 1 - ид кнопки диалога(может быть 1 и 0)
3) nil - ид строки из диалога типа лист(ставь nil если другой)
4) nil - вводимый текст диалога с полем ввода(ставь nil если другой)
sampCloseCurrentDialogWithButton(1)
1) 1 - ид кнопки диалога(может быть 1 и 0), нажмёт на указанную кнопку активного диалога
 
  • Нравится
Реакции: Fleep

Fleep

Участник
61
10
sampSendDialogResponse(228, 1, nil, nil)
1) 228 - ид диалога
2) 1 - ид кнопки диалога(может быть 1 и 0)
3) nil - ид строки из диалога типа лист(ставь nil если другой)
4) nil - вводимый текст диалога с полем ввода(ставь nil если другой)
sampCloseCurrentDialogWithButton(1)
1) 1 - ид кнопки диалога(может быть 1 и 0), нажмёт на указанную кнопку активного диалога
Нужно типо писать function , или в бесконечный цикл ?
 

Cod

Участник
117
15
Как центрировать элементы внутри Imgui?
Именно объекты, не окно (текст, инпуты и т.д)
 

Quasper

Известный
835
354
Как центрировать элементы внутри Imgui?
Именно объекты, не окно (текст, инпуты и т.д)
Lua:
--1) получить ширину окна
--2) получить ширину элемента
--3) поделить ширину окна пополам и вычесть ширину элемента  поделенную  пополам
--3) установить положения для отрисовки элемента
local text = u8'Центрируемый текст'
--begin
local wh = imgui.GetWindowHeight() / 2--получаем цирину окна и делим пополам
local th = imgui.CalcTextSize(text) / 2-- получаем ширину текста и делим пополам
imgui.SetCursorPosX(wh - th)
imgui.Text(text)
--следующий элемент будет отрисован на дефолтных координатах
 
Последнее редактирование:
  • Нравится
Реакции: r0den

Cod

Участник
117
15
Lua:
--1) получить ширину окна
--2) получить ширину элемента
--3) поделить ширину окна пополам и вычесть ширину элемента  поделенную  пополам
--3) установить положения для отрисовки элемента
local text = u8'Центрируемый текст'
--begin
local wh = imgui.GetWindowHeight() / 2--получаем цирину окна и делим пополам
local th = imgui.GetTextLineHeight() / 2-- получаем ширину текста и делим пополам
imgui.SetCursorPosX(wh - th)
imgui.Text(text)
--следующий элемент будет отрисован на дефолтных координатах
1586937059867.png
 

atomlin

Известный
587
449
Привет ребятишки, кто мне сможет расписать данную функцию? (особенно строчку function runTo(x, y, z, runKey, xcam, plusChange) что за атрибуты runKey, xcam, plusChange)


Lua:
local jumpThr
function runTo(x, y, z, runKey, xcam, plusChange)
repeat
local pX, pY, pZ = getCharCoordinates(playerPed)
local gg = fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))
local wp = fix(representIntAsFloat(readMemory(0xB6F248, 4, false)))
local gg = gg + math.pi
local nad = GetAngleBeetweenTwoPoints(x,y)
local test = GetAngleBeetweenTwoPoints(x,y) - gg - math.pi
local dist = getDistanceBetweenCoords3d(x,y,z, pX, pY, pZ)

if plusChange == nil then plusChange = 0.0 end
local ot = 1.5
local waitTime = representIntAsFloat(readMemory(0xB7CB5C, 4, false))/42
wait(waitTime)
if runKey ~= nil then
setGameKeyState(1, -128)
else
setGameKeyState(1, -128)
end
if runKey == 1 then
setGameKeyState(16, 255)
elseif runKey == 2 then
setGameKeyState(21, 255)
elseif runKey == 3 then
if dist >= 5.4 then
if jumpThr == nil then
local x = math.random(1, 100000)
if x >= 94000 then
jumpThr = lua_thread.create(function()
wait(200)
setGameKeyState(14, 255) -- its not jump
jumpThr = nil
end)
end
end
end
elseif runKey == 4 then
setGameKeyState(17, 255)
end
local changeFloat = 0.04 --DEFAULT 0.04
if runKey == 1 then
if dist > 5.0 then changeFloat = 0.08 +plusChange
elseif dist > 3.0 then changeFloat = 0.1 +plusChange
elseif dist > 1.8 then changeFloat = 0.04 + plusChange
end
elseif runKey == 0 then
if dist > 5.0 then changeFloat = 0.08 + plusChange
elseif dist > 3.0 then changeFloat = 0.12 + plusChange
elseif dist > 1.8 then changeFloat = 0.14 +plusChange
end
elseif runKey == 3 then
if dist > 5.0 then changeFloat = 0.08 + plusChange
elseif dist > 3.0 then changeFloat = 0.12 + plusChange
elseif dist > 1.8 then changeFloat = 0.14 +plusChange
end
end
if dist > 1.8 then
if test > -0.1 and test < 0.03 then setCameraPositionUnfixed(xcam, GetAngleBeetweenTwoPoints(x,y))
elseif test < -5.7 and test > -5.93 then setCameraPositionUnfixed(xcam, GetAngleBeetweenTwoPoints(x,y))
elseif test < -6.0 and test > -6.4 then setCameraPositionUnfixed(xcam, GetAngleBeetweenTwoPoints(x,y))
elseif test > 0.04 then setCameraPositionUnfixed(xcam, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+changeFloat)
elseif test < -3.5 and test > -5.67 then setCameraPositionUnfixed(xcam, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))+changeFloat)
else setCameraPositionUnfixed(xcam, fix(representIntAsFloat(readMemory(0xB6F258, 4, false)))-changeFloat)
end
else
setCameraPositionUnfixed(wp, GetAngleBeetweenTwoPoints(x,y))
end
until dist < ot
end

function GetAngleBeetweenTwoPoints(x2,y2)
local x1, y1, z1 = getCharCoordinates(playerPed)
local plus = 0.0
local mode = 1
if x1 < x2 and y1 > y2 then plus = math.pi/2; mode = 2; end
if x1 < x2 and y1 < y2 then plus = math.pi; end
if x1 > x2 and y1 < y2 then plus = math.pi*1.5; mode = 2; end
local lx = x2 - x1
local ly = y2 - y1
lx = math.abs(lx)
ly = math.abs(ly)
if mode == 1 then ly = ly/lx;
else ly = lx/ly; end
ly = math.atan(ly)
ly = ly + plus
return ly
end

function GetXAngle(startDist, dist, startXAngle, x,y,z)
local x1, y1, z1 = getCharCoordinates(playerPed)
local xAngle
if mnum(z) > mnum(z1) then
xAngle = 2
elseif -68 >= z and dist > 2.8 and z1 <= -67.0 then
xAngle = 0
else
local interest = (dist*100)/startDist
if interest == 0 then
interest = 100
end
if interest > 65 then
xAngle = 2*(100-interest)/100-2
else
xAngle = 2*interest/100-2
end
end
return xAngle
end


function mnum(number)
return (number - (number % 0.1))+0.1
end

function fix(angle)
while angle > math.pi do
angle = angle - (math.pi*2)
end
while angle < -math.pi do
angle = angle + (math.pi*2)
end
return angle
end