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

kmsfax

Известный
154
89
ну так добавь проверку, что игрок в машине и обрывай
Тут суть не в проверке, а в том что этот обрыв не проходит, когда стреляешь из снайперки, а игрок в которого ты стреляешь, находится в машине (Возможно что так только на том серверу, где я играю).
В onSendGiveDamage если оборвать - снесёт -45 хп (Хотя сервер должен снести игроку все хп).
В onSendBulletSync если оборвать - снесёт все хп (Как и должно снести сервером).

То есть ни в первом, ни во втором случае обрыва не происходит.
 
Последнее редактирование:

Nold

Известный
29
2
Парни, а как или через чего сделать отображение званий над головами игроков?
 

romacaddy

Известный
Проверенный
235
206
Тут суть не в проверке, а в том что этот обрыв не проходит, когда стреляешь из снайперки, а игрок в которого ты стреляешь, находится в машине (Возможно что так только на том серверу, где я играю).
В onSendGiveDamage если оборвать - снесёт -45 хп (Хотя сервер должен снести игроку все хп).
В onSendBulletSync если оборвать - снесёт все хп (Как и должно снести сервером).

То есть ни в первом, ни во втором случае обрыва не происходит.
попробуй менять кость, в которую ты попадаешь, когда стреляешь перса в машине, ты отправляешь дамаг в голову, и мод мб такой, если в голову со снайпы попадать, убивает сразу
 

makasinuch

Новичок
52
5
1. Как мне проверить что флажок (
Lua:
 [B]dxutAddCheckbox(abazrpconfig, 5, "проба1", 0, 100, 50, 50)
установлен? Может я правильно в коде поставил. Всю инфу брал с этой темы https://www.blast.hk/threads/17438/
Lua:
dialog = dxutCreateDialog(abazrpconfig)
    dxutSetDialogPos(abazrpconfig, 500, 500, 400, 300)
    dxutAddStatic(abazrpconfig, 1, "тест1", 0, 0, 50, 50)
    dxutAddStatic(abazrpconfig, 2, "[B]тест2[/B]", 0, 30, 50, 50)
    dxutAddStatic(abazrpconfig, 3, "[B]тест3[/B]", 0, 60, 50, 50)
    dxutAddStatic(abazrpconfig, 4, "[B]тест4[/B]", 0, 90, 50, 50)
dxutAddCheckbox(abazrpconfig, 5, "проба1", 0, 100, 50, 50)
dxutAddCheckbox(abazrpconfig, 6, "проба2", 30, 100, 50, 50)
dxutAddCheckbox(abazrpconfig, 7, "проба3", 60, 100, 50, 50)
dxutAddCheckbox(abazrpconfig, 8, "проба4", 90, 100, 50, 50)
while true do
wait(0)
local result, event, id = dxutPopEvent(abazrpconfig)
if event == EVENT_CHECKBOX_CHANGED then
    if id == 5 then
2. Как мне открыть диалог нажатием клавиши?
 

kmsfax

Известный
154
89
попробуй менять кость, в которую ты попадаешь, когда стреляешь перса в машине, ты отправляешь дамаг в голову, и мод мб такой, если в голову со снайпы попадать, убивает сразу
Ну таки да, я и написал сразу, что сервер убивает с одного выстрела, только не в голову, а в любую часть тела.
Проблему решил, заигнорив одновременно onSendGiveDamage и onSendBulletSync.
 

san0

Известный
Друг
411
268
Если ты использовал гайд по клео, нет никаких трудностей узнать на вики какая функция соответствует опкоду.
Например, для 1-го случая
BdWFe9v.png

2. проверить нажатие клавиши и dxutSetDialogVisible(DxutDialog dialog, bool visible)
 

Vadgal

Новичок
17
1
Ребятки, подскажите функцию, с помощью которой можно вывести ID скина на моем персонаже ?
 

Moonlight_Ru

Известный
66
21
Ребята, нужна ваша помощь. Только начал изучать Lua, решил написать первый скрипт. Скрипт мониторит заходы / выходы игроков на сервер и выводит соответствующие сообщения в чат, так же скрипт можно включать и выключать, при этом при каждом включении / выключении в ini файле меняется значение. Это всё работает. Но только в том случае, если вручную создать ini файл, сделать в нём нужную секцию и кей.
А как сделать так, чтобы файл создавался сам? Думал, что он создаётся с помощью inicfg.save(), но это не так, либо я просто криворук. Помогите пожалуйста, вот код, если надо.

Lua:
local login = require 'lib.samp.events'
local inicfg = require 'inicfg'
local InOutLogSpawned = 0
local OnOffCommand = nil
local InOutLogData = nil

function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("iol", InOutLog)
    InOutLogData = inicfg.load(nil, "settings")
    if InOutLogData == nil then
        InOutLogData = {
            InOutLogSettings = {
                DefaultSetting = 0,
            }
        }
        inicfg.save(InOutLogData, "settings")
        OnOffCommand = 0
    else
    OnOffCommand = InOutLogData.InOutLogSettings.DefaultSetting
end
    repeat
        wait(0)
    until sampIsLocalPlayerSpawned()
    InOutLogSpawned = 1
    wait(-1)
end

function login.onPlayerJoin(playerId, color, isNpc, nickname)
    if OnOffCommand == 1 and InOutLogSpawned == 1 then
        sampAddChatMessage(string.format("*** %s[%d] подключился.", nickname, playerId), 0x999999)
    end
end

function login.onPlayerQuit(playerId, reason)
    if OnOffCommand == 1 and InOutLogSpawned == 1 then
        nickname = sampGetPlayerNickname(playerId)
        if reason == 0 then
            reason_s = string.format("Ошибка")
        elseif reason == 1 then
            reason_s = string.format("Вышел")
        else
            reason_s = string.format("Кик/Бан")
        end
        sampAddChatMessage(string.format("*** %s[%d] покинул сервер (%s).", nickname, playerId, reason_s), 0x999999)
    end
end

function InOutLog()
    if OnOffCommand == 0 then
        OnOffCommand = 1
        sampAddChatMessage(string.format("*** Мониторинг входов/выходов игроков включен."), 0xAAFFAA)
        InOutLogData = {
            InOutLogSettings = {
                DefaultSetting = 1,
            }
        }
        inicfg.save(InOutLogData, "settings")
    elseif OnOffCommand == 1 then
        OnOffCommand = 0
        sampAddChatMessage(string.format("*** Мониторинг входов/выходов игроков выключен."), 0xFFAAAA)
        InOutLogData = {
            InOutLogSettings = {
                DefaultSetting = 0,
            }
        }
        inicfg.save(InOutLogData, "settings")
    end
end
 

N1kkey

Новичок
2
0
Как биндить через Lua , чтобы он работал , как тот же AHK ?
Если можно , напишите простой пример .
 
Последнее редактирование:

4el0ve4ik

Известный
Всефорумный модератор
1,550
1,343
Как биндить через Lua , чтобы он работал , как тот же AHK ?
Если можно , напишите простой пример .
Lua:
require "lib.moonloader"
function main()
  while not isSampAvailable() do wait(0) end
  while true do
    wait(0)
    if isKeyJustPressed(VK_H) then
      sampSendChat("бип-бип")
    end
  end
end
Если нажать клавишу h отправит "бип-бип" серверу
 

itsLegend

Фонд борьбы за жуков 🐞
Администратор
2,696
1,468
Ребята, нужна ваша помощь. Только начал изучать Lua, решил написать первый скрипт. Скрипт мониторит заходы / выходы игроков на сервер и выводит соответствующие сообщения в чат, так же скрипт можно включать и выключать, при этом при каждом включении / выключении в ini файле меняется значение. Это всё работает. Но только в том случае, если вручную создать ini файл, сделать в нём нужную секцию и кей.
А как сделать так, чтобы файл создавался сам? Думал, что он создаётся с помощью inicfg.save(), но это не так, либо я просто криворук. Помогите пожалуйста, вот код, если надо.
Он создается с помощью inicfg.save, только для этого должна существовать папка config в папке moonloader.
 
  • Нравится
Реакции: Moonlight_Ru

Forevor

Известный
77
5
Помогите сделать скрипт, который при появлении того или иного текста в чате писал команду.

Lua:
  str, --[[string]] prefstr, --[[int]] colstr, --[[int]] pcolstr = sampGetChatString(--[[int]] 99)
    if str == "{0088ff}[Вопрос] {33CCFF}" then -- сравить строку на полное соответствие
    end
        if string.find(str, "{0088ff}[Вопрос] {33CCFF}", 0, true) ~= nil then -- проверить наличие подстроки "Строка" в строке str
            reprts()
            sampAddChatMessage("{cd0000}1", 0x0088ff)
      end

function reprts()
sampSendChat("/reports")
end
end
Не понимаю почему не работает.
 
Последнее редактирование: