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

Shepi

Активный
178
37
Посмотреть вложение 112420
Все равно такая фигня, настройки вот такие. (должно чтобы был небольшой отступ в child, а текст прям на window залазит)
Посмотреть вложение 112421

Вот так вот в коде:
Посмотреть вложение 112422
Скинь пж код закругленности кнопок и подобного
 

Стэнфорд

Потрачен
1,058
543
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
os.date("%d.%m.%Y")
вместо даты выводит 59:08/29/21:2021 , пробовал разные варианты, все равно так выводит
 

danywa

Активный
358
50
Lua:
local ss = false

main = function()
    sampRegisterChatCommand("spp", function() s = not s if s then ss = true else ss = false end end)
    while true do wait(0)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local distant = getDistanceBetweenCoords3d(x, y, z, marker_x, marker_y, marker_z)
        if ss then printString(distant, 1000) end
    end

onReceiveRpc = function(int, bit)
    if int == 38 then
        local typeRace = raknetBitStreamReadInt8(bit)
        marker_x = raknetBitStreamReadFloat(bit)
        marker_y = raknetBitStreamReadFloat(bit)
        marker_z = raknetBitStreamReadFloat(bit)
        local nextX = raknetBitStreamReadFloat(bit)
        local nextY = raknetBitStreamReadFloat(bit)
        local nextZ = raknetBitStreamReadFloat(bit)
        local radius = raknetBitStreamReadFloat(bit)
     elseif int == 107 then
        marker_x = raknetBitStreamReadFloat(bit)
        marker_y = raknetBitStreamReadFloat(bit)
        marker_z = raknetBitStreamReadFloat(bit)
        local rdus = raknetBitStreamReadFloat(bit)
    end
end
Как сделать чтобы дистанция все время была на экране, а не на одну секунду
 

atomlin

Известный
587
449
Lua:
local ss = false

main = function()
    sampRegisterChatCommand("spp", function() s = not s if s then ss = true else ss = false end end)
    while true do wait(0)
        local x, y, z = getCharCoordinates(PLAYER_PED)
        local distant = getDistanceBetweenCoords3d(x, y, z, marker_x, marker_y, marker_z)
        if ss then printString(distant, 1000) end
    end

onReceiveRpc = function(int, bit)
    if int == 38 then
        local typeRace = raknetBitStreamReadInt8(bit)
        marker_x = raknetBitStreamReadFloat(bit)
        marker_y = raknetBitStreamReadFloat(bit)
        marker_z = raknetBitStreamReadFloat(bit)
        local nextX = raknetBitStreamReadFloat(bit)
        local nextY = raknetBitStreamReadFloat(bit)
        local nextZ = raknetBitStreamReadFloat(bit)
        local radius = raknetBitStreamReadFloat(bit)
     elseif int == 107 then
        marker_x = raknetBitStreamReadFloat(bit)
        marker_y = raknetBitStreamReadFloat(bit)
        marker_z = raknetBitStreamReadFloat(bit)
        local rdus = raknetBitStreamReadFloat(bit)
    end
end
Как сделать чтобы дистанция все время была на экране, а не на одну секунду
Lua:
if ss then printString(distant) end
 
  • Нравится
Реакции: danywa

danywa

Активный
358
50
Как можно найти дистанцию от моего персонажа до точки, но уже с своими координатами из таблицы
Lua:
local PosT = {
    [1] = {-2681.2800292969, 2149.919921875, 14.445400238037}
    }

local x, y, z = getCharCoordinates(PLAYER_PED)
local distant = getDistanceBetweenCoords3d(x, y, z, должны быть три координаты)
 

Стэнфорд

Потрачен
1,058
543
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
Хелп, нужно что бы функция выполнялась каждый раз при входе в игру. При перезапуске скрипта она не должна работать, как это можно сделать?
 

chapo

чопа сребдс // @moujeek
Модератор
8,951
11,734
Хелп, нужно что бы функция выполнялась каждый раз при входе в игру. При перезапуске скрипта она не должна работать, как это можно сделать?
Lua:
local sampev = require 'lib.samp.events'
local workay_suka = true

function sampev.onSendClientJoin(version, mod, nickname, response, authKey, clientVer, response2)
    if workay_suka then
        workay_suka = false -- что бы не срабатывало после реконнекта
        --code
    end
end
 

barjik

Известный
462
192
Почему при перезагрузке moonloader'a, и при перезаходе в игру значение не сохраняется?
Lua:
require "lib.moonloader"
local imgui = require "imgui"
local encoding = require "encoding"
encoding.default = "CP1251"
u8 = encoding.UTF8

local inicfg = require 'inicfg'
local cfg = inicfg.load({
    settings = {
        rpgun = true
        }
}, "GUNS")

local one_window = imgui.ImBool(false)
local two_window = imgui.ImBool(false)
local imgui = require 'imgui'
checkbox = imgui.ImBool(false)

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
        while not isSampAvailable() do wait(100) end
        sampRegisterChatCommand("h1", cmd_h1)
        sampRegisterChatCommand("h2", cmd_h2)
        while true do
           wait(0)   

        if lastgun ~= getCurrentCharWeapon(PLAYER_PED) and cfg.settings.rpgun then
            local gun = getCurrentCharWeapon(PLAYER_PED)
            if gun == 23 then
                sampSendChat('/me достал taser-x24 из кобуры')
            elseif gun == 24 then
                sampSendChat('/me достал пистолет Desert Eagle из кобуры')
            elseif gun == 25 then
                sampSendChat('/me достал Shotgun n из-за спины')
            elseif gun == 28 then
                sampSendChat('/me достал Micro Uzi из-за спины')
            elseif gun == 29 then
                sampSendChat('/me взял MP-5 в руки')
            elseif gun == 30 then
                sampSendChat('/me взял автомат АК-47 в руки')
            elseif gun == 31 then
                sampSendChat('/me взял карабин М4А1 в руки')
            elseif gun == 33 then
                sampSendChat('/me взял винтовку в руки')
            elseif gun == 34 then
                sampSendChat('/me взял снайперскую винтовку в руки')
            elseif gun == 0 then
                sampSendChat('/me убрал оружие')
            end
            lastgun = gun   
            
            end
        end
    end           

function cmd_h1()
    one_window.v = not one_window.v
    imgui.Process = one_window.v
end

function cmd_h2()
    two_window.v = not two_window.v
    imgui.Process = two_window.v
end

function imgui.OnDrawFrame()
    if not one_window.v and not two_window.v then
    imgui.Process = false
    end
    
    if one_window.v then
    imgui.Begin(u8"okno1", one_window)
    if imgui.Checkbox(u8' RP guns', checkbox) then
    cfg.settings.rpgun = not cfg.settings.rpgun
    if cfg.settings.rpgun then
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {008000}включена.', -1)   
    else
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {FF0000}выключена.', -1)       
    end
end
imgui.End()
end

    if two_window.v then
    imgui.Begin(u8"okno2", two_window)
    imgui.Text(u8"hi")
    imgui.End()
    end
end

function onScriptTerminate(script, quitGame)
  if script == thisScript() then
    inicfg.save(cfg, "GUNS")
    end
end
 

Sanchez.

Известный
705
189
Почему при перезагрузке moonloader'a, и при перезаходе в игру значение не сохраняется?
Lua:
require "lib.moonloader"
local imgui = require "imgui"
local encoding = require "encoding"
encoding.default = "CP1251"
u8 = encoding.UTF8

local inicfg = require 'inicfg'
local cfg = inicfg.load({
    settings = {
        rpgun = true
        }
}, "GUNS")

local one_window = imgui.ImBool(false)
local two_window = imgui.ImBool(false)
local imgui = require 'imgui'
checkbox = imgui.ImBool(false)

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
        while not isSampAvailable() do wait(100) end
        sampRegisterChatCommand("h1", cmd_h1)
        sampRegisterChatCommand("h2", cmd_h2)
        while true do
           wait(0)  

        if lastgun ~= getCurrentCharWeapon(PLAYER_PED) and cfg.settings.rpgun then
            local gun = getCurrentCharWeapon(PLAYER_PED)
            if gun == 23 then
                sampSendChat('/me достал taser-x24 из кобуры')
            elseif gun == 24 then
                sampSendChat('/me достал пистолет Desert Eagle из кобуры')
            elseif gun == 25 then
                sampSendChat('/me достал Shotgun n из-за спины')
            elseif gun == 28 then
                sampSendChat('/me достал Micro Uzi из-за спины')
            elseif gun == 29 then
                sampSendChat('/me взял MP-5 в руки')
            elseif gun == 30 then
                sampSendChat('/me взял автомат АК-47 в руки')
            elseif gun == 31 then
                sampSendChat('/me взял карабин М4А1 в руки')
            elseif gun == 33 then
                sampSendChat('/me взял винтовку в руки')
            elseif gun == 34 then
                sampSendChat('/me взял снайперскую винтовку в руки')
            elseif gun == 0 then
                sampSendChat('/me убрал оружие')
            end
            lastgun = gun  
           
            end
        end
    end          

function cmd_h1()
    one_window.v = not one_window.v
    imgui.Process = one_window.v
end

function cmd_h2()
    two_window.v = not two_window.v
    imgui.Process = two_window.v
end

function imgui.OnDrawFrame()
    if not one_window.v and not two_window.v then
    imgui.Process = false
    end
   
    if one_window.v then
    imgui.Begin(u8"okno1", one_window)
    if imgui.Checkbox(u8' RP guns', checkbox) then
    cfg.settings.rpgun = not cfg.settings.rpgun
    if cfg.settings.rpgun then
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {008000}включена.', -1)  
    else
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {FF0000}выключена.', -1)      
    end
end
imgui.End()
end

    if two_window.v then
    imgui.Begin(u8"okno2", two_window)
    imgui.Text(u8"hi")
    imgui.End()
    end
end

function onScriptTerminate(script, quitGame)
  if script == thisScript() then
    inicfg.save(cfg, "GUNS")
    end
end
Lua:
require "lib.moonloader"
local imgui = require "imgui"
local encoding = require "encoding"
encoding.default = "CP1251"
u8 = encoding.UTF8

local inicfg = require 'inicfg'
local cfg = inicfg.load({
    settings = {
        rpgun = true
        }
}, "GUNS")

local one_window = imgui.ImBool(false)
local two_window = imgui.ImBool(false)
local imgui = require 'imgui'
checkbox = imgui.ImBool(cfg.settings.rpgun)

function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
        while not isSampAvailable() do wait(100) end
        sampRegisterChatCommand("h1", cmd_h1)
        sampRegisterChatCommand("h2", cmd_h2)
        while true do
           wait(0)   

        if lastgun ~= getCurrentCharWeapon(PLAYER_PED) and cfg.settings.rpgun then
            local gun = getCurrentCharWeapon(PLAYER_PED)
            if gun == 23 then
                sampSendChat('/me достал taser-x24 из кобуры')
            elseif gun == 24 then
                sampSendChat('/me достал пистолет Desert Eagle из кобуры')
            elseif gun == 25 then
                sampSendChat('/me достал Shotgun n из-за спины')
            elseif gun == 28 then
                sampSendChat('/me достал Micro Uzi из-за спины')
            elseif gun == 29 then
                sampSendChat('/me взял MP-5 в руки')
            elseif gun == 30 then
                sampSendChat('/me взял автомат АК-47 в руки')
            elseif gun == 31 then
                sampSendChat('/me взял карабин М4А1 в руки')
            elseif gun == 33 then
                sampSendChat('/me взял винтовку в руки')
            elseif gun == 34 then
                sampSendChat('/me взял снайперскую винтовку в руки')
            elseif gun == 0 then
                sampSendChat('/me убрал оружие')
            end
            lastgun = gun   
            
            end
        end
    end           

function cmd_h1()
    one_window.v = not one_window.v
    imgui.Process = one_window.v
end

function cmd_h2()
    two_window.v = not two_window.v
    imgui.Process = two_window.v
end

function imgui.OnDrawFrame()
    if not one_window.v and not two_window.v then
    imgui.Process = false
    end
    
    if one_window.v then
    imgui.Begin(u8"okno1", one_window)
    if imgui.Checkbox(u8' RP guns', checkbox) then
    cfg.settings.rpgun = not cfg.settings.rpgun
    inicfg.save(cfg, 'Название твоего файла.ini')
    if cfg.settings.rpgun then
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {008000}включена.', -1)   
    else
      sampAddChatMessage('{FFFFFF}Отыгровка оружия {FF0000}выключена.', -1)       
    end
end
imgui.End()
end

    if two_window.v then
    imgui.Begin(u8"okno2", two_window)
    imgui.Text(u8"hi")
    imgui.End()
    end
end

function onScriptTerminate(script, quitGame)
  if script == thisScript() then
    inicfg.save(cfg, "GUNS")
    end
end
 
  • Влюблен
Реакции: barjik

danywa

Активный
358
50
Lua:
local text = renderCreateFont("Verdana", 12, 9)
local render_text = false

local trainPos =
    {
    [1] = {-2681.2800292969, 2149.919921875, 14.445400238037}; [2] = {-2615.6999511719, 1396.1600341797, 6.4714798927307}; [3] = {-2713.6999511719, 1026.4100341797, 1.7189899682999}; [4] = {-2708.169921875, 634.75799560547, 5.2032399177551}; [5] = {-2702.580078125, 243.10299682617, 8.6877498626709};
    }
    
main = function()
    sampRegisterChatCommand("sps", function() render_text = true end)
    while true do wait(0) 
            if render_text then
                local x, y, z = getCharCoordinates(PLAYER_PED)
                local dist = getDistanceBetweenCoords3d(x, y, z, table.unpack(trainPos[1]))
                local incar = isCharInAnyCar(PLAYER_PED)
                renderFontDrawText(text, 'dist: '..dist, 100, 400, 0xFFFFFFFF)
                if dist < 2 then
                    i = 1
                    i = i + 1
                    dist = getDistanceBetweenCoords3d(x, y, z,  table.unpack(trainPos[i]))
                end
            end
    end
end

Как решить проблему что условие с дистанцией не выполняется и не переходит к следующему значению из массива