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

Garrus

Известный
159
20
Консоль открыть, в заголовке будет написано или почитать текст в консоли, там тоже будет
Я имею ввиду, через скрипт. У меня скрипт не работает с версией СФ, ниже 5.3. Хочу поставить соответствующую проверку. И если у тебя есть, скинь пожалуйста СФ версии 5.2.2.
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Я имею ввиду, через скрипт. У меня скрипт не работает с версией СФ, ниже 5.3. Хочу поставить соответствующую проверку. И если у тебя есть, скинь пожалуйста СФ версии 5.2.2.
Не, не могу с этим помочь, извини.
 

Garrus

Известный
159
20
Еще такой нюанс. Функция получения опыта игрока (local score = sampGetPlayerScore(id)) не всегда правильно возвращает опыт, часто возвращает просто "0", приходится вызывать функцию второй раз или использовать в цикле. Такое было еще на клео)
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Еще такой нюанс. Функция получения опыта игрока (local score = sampGetPlayerScore(id)) не всегда правильно возвращает опыт, часто возвращает просто "0", приходится вызывать функцию второй раз или использовать в цикле. Такое было еще на клео)
Когда игрок конектится - тогда и будет 0 выдавать, а вообще почти во всех своих скриптах я использовал в циклах
 

Garrus

Известный
159
20
Когда игрок конектится - тогда и будет 0 выдавать, а вообще почти во всех своих скриптах я использовал в циклах
Функция иногда возвращает 0 тогда, когда игрок законнектился и в табе значение опыта не равно нулю. А если использовать в цикле, то такой проблемы не будет.
 

FYP

Известный
Автор темы
Администратор
1,764
5,929
Еще такой нюанс. Функция получения опыта игрока (local score = sampGetPlayerScore(id)) не всегда правильно возвращает опыт, часто возвращает просто "0", приходится вызывать функцию второй раз или использовать в цикле. Такое было еще на клео)
это проблема самого sampfuncs, там немного тупая реализация этого опкода. можно сделать функцию, которая будет ждать пока очки не обновятся. типо while sampGetPlayerScore(id) == 0 do wait(0) end (это просто пример, именно так лучше не делать)
 
  • Нравится
Реакции: Garrus

newYear

Потрачен
9
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
почему при попытке получить structElement из sampGetPlayerStruct выдаёт ноль? Что я делаю не так?
Код:
PS = sampGetPlayerStructPtr(id)
g = getStructElement(PS,0x18,12)

пс, я пытаюсь получить координаты игрока из структуры игрока, а оффсеты и размер взял из функи на клео, делающей тоже самое
 

CAPTA!N

Новичок
220
51
Наверное так
Lua:
PS = sampGetPlayerStructPtr(id)
g = getStructElement(PS,sampGetBase() + 0x18,12)
 

FYP

Известный
Автор темы
Администратор
1,764
5,929
почему при попытке получить structElement из sampGetPlayerStruct выдаёт ноль? Что я делаю не так?
Код:
PS = sampGetPlayerStructPtr(id)
g = getStructElement(PS,0x18,12)

пс, я пытаюсь получить координаты игрока из структуры игрока, а оффсеты и размер взял из функи на клео, делающей тоже самое
потому что размер не может быть больше 4. и вообще, зачем получать координаты из памяти, когда есть функции?
Наверное так
Lua:
PS = sampGetPlayerStructPtr(id)
g = getStructElement(PS,sampGetBase() + 0x18,12)
нет, не так.
 
  • Нравится
Реакции: CAPTA!N

newYear

Потрачен
9
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
потому что размер не может быть больше 4. и вообще, зачем получать координаты из памяти, когда есть функции?

нет, не так.
по оффсету 18 должен начинаться блок fPosition, и первым в нём стоит X, а вот насчёт размера я не подумал. Попробую поставить четыре.
Мне нужно получить из структуры, чтобы потом в неё же записать и отправлять фейковую позицию - для удобства просто, поскольку всё равно придётся со структурой работать
 

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
что не так? с типами вроде не напутал
И как сделать что бы диалог не открывался?(тобишь возвратить false)
Lua:
function onReciveRPC(id, bs)
  if id == 61 then
  isActived = raknetBitStreamReadInt32(bs)
  dstyle = raknetBitStreamReadInt8(bs)
  dialid = raknetBitStreamReadInt16(bs)
  titlen = raknetBitStreamReadInt8(bs)
  title = raknetBitStreamReadString(bs, titlen)
  button1len = raknetBitStreamReadInt8(bs)
  button1 = raknetBitStreamReadString(bs, button1len)
  button2len = raknetBitStreamReadInt8(bs)
  button2 = raknetBitStreamReadString(bs, button2len)
  text = raknetBitStreamDecodeString(bs, 257)
    if dialid == 10004 then
      file = io.open("moonloader/config/stat.txt", "w")
      file:write(text)
      file:close()
    end
  end
end


function main()
if not isSampfuncsLoaded() or not isSampLoaded() then return end
  while true do
    wait(0)
  end
end
 
Последнее редактирование:

FYP

Известный
Автор темы
Администратор
1,764
5,929
  • Нравится
Реакции: etereon и 4el0ve4ik

newYear

Потрачен
9
0
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
help me up, guys
Y и Z после спавна выводятся корректно, а вот X хоть убей не хочет выводиться (вернее, выводится, если убрать преобразование в плавающий тип, но явно не координата X, а какая-то бредятина), где ошибка?
пробовал соседние адреса, перепробовал каждый второй начиная с 0x2 и до 0x36, уже и не знаю, куда потерялась из структуры координата X
Код:
while true do
  wait(50)
  nomeow, meow = sampGetPlayerIdByCharHandle(playerPed)
  PS1 = sampGetPlayerStructPtr(meow)
  SX = getStructElement(PS1,0x18,4)
  RX = representIntAsFloat(SX)
  SY = getStructElement(PS1,0x22,4)
  RY = representIntAsFloat(SY)
  SZ = getStructElement(PS1,0x26,4)
  RZ = representIntAsFloat(SZ)
  sampAddChatMessage(string.format('(%f)\b(%f)\b(%f)',RX,RY,RZ),555555)
  end
 

hnnssy

Известный
Друг
2,684
2,767
help me up, guys
Y и Z после спавна выводятся корректно, а вот X хоть убей не хочет выводиться (вернее, выводится, если убрать преобразование в плавающий тип, но явно не координата X, а какая-то бредятина), где ошибка?
пробовал соседние адреса, перепробовал каждый второй начиная с 0x2 и до 0x36, уже и не знаю, куда потерялась из структуры координата X
Код:
while true do
  wait(50)
  nomeow, meow = sampGetPlayerIdByCharHandle(playerPed)
  PS1 = sampGetPlayerStructPtr(meow)
  SX = getStructElement(PS1,0x18,4)
  RX = representIntAsFloat(SX)
  SY = getStructElement(PS1,0x22,4)
  RY = representIntAsFloat(SY)
  SZ = getStructElement(PS1,0x26,4)
  RZ = representIntAsFloat(SZ)
  sampAddChatMessage(string.format('(%f)\b(%f)\b(%f)',RX,RY,RZ),555555)
  end
координаты и так во флоат же хранятся