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

Licht

Известный
238
32
Вообщем помогите, суть такова:
Задал переменку wtable = {}
я ловлю текст розыска и вытаскиваю переменки из onServerMessage
Переменки такие: whogive, suspect, lvl_su, reason
в таблу вписываю с помощью table.insert в wtable и тд...
как содержимое этой фигни при вводе кмд переносить в тектовой файл формата .txt?
Читаю содержимое через
sampShowDialog(97987, '{9966cc}'..script.this.name..' {ffffff} | Лог выдачи розыска', table.concat(wtable, '\n'), '»', 'x', 0)
Мун 0.26.5
@date хелпни ты вродь шаришь)
 

Pu$$y

Участник
80
2
Well, I use this code to check whoever has level 50 at the server. It is not working and sometimes it gives me crashes, What's wrong?
Lua:
function assassin()
    local id = 0
    AllPlayers = sampGetMaxPlayerId()
    while id < AllPlayers do
        level = sampGetPlayerScore(id)
        id = id + 1
            if level == 50 then
                nameofplayer = sampGetPlayerNickname(id)
                sampAddChatMessage(nameofplayer, 0xFFFFFF)
            end
            end
end
 

paulohardy

Известный
Всефорумный модератор
1,997
1,337
Well, I use this code to check whoever has level 50 at the server. It is not working and sometimes it gives me crashes, What's wrong?
Lua:
function assassin()
    local id = 0
    AllPlayers = sampGetMaxPlayerId()
    while id < AllPlayers do
        level = sampGetPlayerScore(id)
        id = id + 1
            if level == 50 then
                nameofplayer = sampGetPlayerNickname(id)
                sampAddChatMessage(nameofplayer, 0xFFFFFF)
            end
            end
end
use sampIsPlayerConnected(id)
 

Dmitriy Makarov

25.05.2021
Проверенный
2,515
1,141
Lua:
-- main
_, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
mynick = sampGetPlayerNickname(myid)
   
-- while true do
if isKeyJustPressed(VK_NUMPAD5) then
    lua_thread.create(function()
        sampSendChat("/do В кармане "..sampGetPlayerNickname(myid):gsub('_', ' ').." балаклава.")
        wait(200)
        sampSendChat("/mask")
        wait(200)
        sampSendChat("/me достал балаклаву из кармана и надел на голову")
        wait(200)
        sampSendChat("/reset")
        wait(500)
        sampSendChat("/do Маска на голове.")
     end)
end
Если при заходе в игру начать отыгровку, то вместо моего ника в (sampGetPlayerNickName) выводит ник игрока с 0 ид. После релоада скрипта уже все норм, выводит мой.
В чем может быть проблема?
 

paulohardy

Известный
Всефорумный модератор
1,997
1,337
Lua:
-- main
_, myid = sampGetPlayerIdByCharHandle(PLAYER_PED)
mynick = sampGetPlayerNickname(myid)

-- while true do
if isKeyJustPressed(VK_NUMPAD5) then
    lua_thread.create(function()
        sampSendChat("/do В кармане "..sampGetPlayerNickname(myid):gsub('_', ' ').." балаклава.")
        wait(200)
        sampSendChat("/mask")
        wait(200)
        sampSendChat("/me достал балаклаву из кармана и надел на голову")
        wait(200)
        sampSendChat("/reset")
        wait(500)
        sampSendChat("/do Маска на голове.")
     end)
end
Если при заходе в игру начать отыгровку, то вместо моего ника в (sampGetPlayerNickName) выводит ник игрока с 0 ид. После релоада скрипта уже все норм, выводит мой.
В чем может быть проблема?
получай ник после загрузки сампа или же в самой отыгровке
sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(1))):gsub('_', ' ')
 
  • Нравится
Реакции: Dmitriy Makarov

TSIDEX

Известный
86
8
Как сделать, чтобы по нажатию кнопки действие выполнялось до тех пор, пока ты его не остановишь этой же кнопкой?
 

paulohardy

Известный
Всефорумный модератор
1,997
1,337
Как сделать, чтобы по нажатию кнопки действие выполнялось до тех пор, пока ты его не остановишь этой же кнопкой?
Lua:
--function main()

while true do
 wait(0)
 if isKeyJustPressed(номер кнопки) then
  act = not act
 end
 if act then
  --блок кода
 end
end
 

TSIDEX

Известный
86
8
Как удалить определённую строку в чате или чтобы строка не появлялась в чате.
 
Последнее редактирование:

Lucifer Melton

Активный
164
57
Lua:
-- ини

i_test = u8'/my_cmd'

local input = imgui.ImBuffer(tostring(путь.i_test), 256)

-- main

sampRegisterChatCommand('my_cmd', function()
    my_window.v = not my_window.v
end)

-- imgui

if imgui.InputText(u8'Введите Команду', input) then
    путь.i_test = input.v
    inicfg.save(путь, 'Test.ini')
    sampUnregisterChatCommand('my_cmd')
    sampRegisterChatCommand(input.v)
end

Lua:
freezeCharPosition(PLAYER_PED, false)

Нет

Lua:
function isPlayerInStream(playerName)
    for i = 0, 999 do
        local player = getPlayer(i)
        if player then
            if player.inStream and player.name == playerName then
                return true
            end
        end
    end
    return false
end

function onServerMessage(msg)
    local adminName, playerName = msg:match('Администратор (%S+) забанил игрока (%S+)')
    if adminName and playerName then
        local botName = getNickName()
        if playerName ~= botName then
            if isPlayerInStream(playerName) then
                sampProcessChatInput('/q')
            end
        end
    end
end
фигни людям не советуй пожалуйста
Помогите, как реализовать например я хочу создать окошко INPUTTEXT чтобы туда написать команду для активации скрипта? я не могу сделать сохранение этой
команды. Посмотреть вложение 53116
Lua:
local set = inicfg.load(nil, "test")
if set == nil then
    ini = { settings = { command = "test" } }
    inicfg.save(ini, "test")
    set = inicfg.load(nil, "test")
end

local main_window_state = imgui.ImBool(false)
local command = imgui.ImBuffer(u8(tostring(set.settings.command)), 256)

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then error("need sampfuncs") end
    while not isSampAvailable() do wait(100) end
    while true do
        wait(0)
        imgui.Process = main_window_state.v
    end
end

function imgui.OnDrawFrame()
    local sw, sh = getScreenResolution()
    imgui.SetNextWindowSize(imgui.ImVec2(270, 60), imgui.Cond.FirstUseEver)
    imgui.SetNextWindowPos(imgui.ImVec2((sw / 2), sh / 2), imgui.Cond.FirstUseEver, imgui.ImVec2(0.5, 0.5))
    imgui.Begin(u8"test imgui", main_window_state)
    imgui.PushItemWidth(90.00)
    imgui.InputText(u8"Команда", command)
    imgui.PopItemWidth(); imgui.SameLine(nil, 3)
    imgui.TextQuestion(u8"Пишите команду без этого символа \"/\""); imgui.SameLine(nil, 3)
    if imgui.Button(u8"Сохранить") then
        set.settings.command = u8:decode(command.v)
        inicfg.save(set, "test")
        sampAddChatMessage("Теперь новая команда: \"/"..set.settings.command.."\"", 4291743438)
    end
    imgui.End()
end

function imgui.TextQuestion(text)
    imgui.TextDisabled("(?)")
    if imgui.IsItemHovered() then
        imgui.BeginTooltip()
        imgui.PushTextWrapPos(450)
        imgui.TextUnformatted(text)
        imgui.PopTextWrapPos()
        imgui.EndTooltip()
    end
end

function onSendRpc(id, bs, priority, reliability, orderingChannel, shiftTs) -- он получает исходящих RPC
    if id == 50 then -- onSendCommand
        local cmd = raknetBitStreamReadString(bs, raknetBitStreamReadInt32(bs))
        if cmd == "/"..set.settings.command then
            main_window_state.v = not main_window_state.v
        end
    end
end

-- или вот так

-- function samp.onSendCommand(cmd)
    -- if cmd == "/"..set.settings.command then
        -- main_window_state.v = not main_window_state.v
    -- end
-- end
 
  • Нравится
Реакции: degrando

Fleep

Участник
61
11
как сделать чтобы я написал команду , действие началось и закончилось когда я сново введу команду
 

Pasquale Developer

Известный
109
8
Помогите ошибка такова что при заходе на сервер скрипт крашиться а вот после нажатия клавиши Кнтрл + R, все скрипты хорошо работают...


Код скрипта:
require "moonloader"
local imgui = require "imgui"
local encoding = require "encoding"
local samp = require "samp.events"
require 'lib.sampfuncs'
require 'lib.moonloader'
local memory = require "memory"
local vkeys = require 'vkeys'

require 'lib.moonloader'
local mem = require "memory"
local sampev = require 'lib.samp.events'
local ts = 0

encoding.default = 'CP1251'
u8 = encoding.UTF8
script_name("hardhelper")
script_authors("NOAH HARD")
script_version("0.1")

_, id = sampGetPlayerIdByCharHandle(PLAYER_PED)
nick = sampGetPlayerNickname(id)
nick = nick:gsub("_", " ")

ip, port = sampGetCurrentServerAddress()
ip = ip..":"..port
if ip ~= "54.37.142.73:7777" then
thisScript():unload()
end

function main()
while not sampIsLocalPlayerSpawned() do wait(10) end
wait(10)
sampAddChatMessage("{FF0000}[LUA] {FF8C00}Приветствую: " .. nick .. " [" .. id.. "]", 0xFFFF0000)
wait(10)
sampAddChatMessage("{FF0000}[LUA] {FF8C00}Автор скрипта: Timofey Pankratov", 0xFFFF0000)

while true do
wait(2000)
if getCharHealth (PLAYER_PED) <= 45 then
lua_thread.create(function()
sampSendChat('/healme')
wait(2000) -- задержка чтобы не зафлудило и подождало, иначе аптечек не останется
end) -- оно не успевает получить данные
end
end
end

function samp.onServerMessage(color, text)
if text:find('Не флудите') then
lua_thread.create(function()
wait(3000)
sampSendChat('Кхм..')
end)
end
if text:find('Игроку уже сделали предложение. Он должен принять или отклонить его') then
lua_thread.create(function()
wait(10)
sampSendChat('/n Вам уже сделали предложение, нажмите "N", дабы отклонить его.')
end)
end
if text:find('У пациента нет с собой столько денег') then
lua_thread.create(function()
wait(10)
sampSendChat('К сожалению, у вас не достаточно финансовых средств для платного лечения. Всего доброго.')
end)
end
if text:find('Этот игрок не лежит в больнице') then
lua_thread.create(function()
wait(10)
sampSendChat('Попрошу вас занять койку в свободной палате и мы сразу же начнем лечение.')
wait(1000)
sampSendChat('/n /med - у свободной койки.')
end)
end
if text:find('У Вас закончились лекарства. Возьмите их на складе') then
lua_thread.create(function()
wait(10)
sampSendChat('Прошу прощение, мне нужно отлучиться на 1 минуту за медикаментами.')
end)
end
if text:find('Вы предложили (.*) пройти у Вас курс платного лечения за') then
lua_thread.create(function()

wait(10)
sampSendChat('/do Медецинаская сумка в руках.')
wait(1000)
sampSendChat('/me открыв медецинскую сумку достает от туда аскорбинку')
wait(1000)
sampSendChat('/do Аскорбинка в руках.')
wait(1000)
sampSendChat('/me передает стакан с водой и аскорбинку человеку напротив')
wait(1000)
sampSendChat('/anim 21')
wait(3500)
sampSendChat('Это вам должно помочь! Больше не болейте COVID-19.')
end)
end
end