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

.Makarov.

Известный
188
36
Здравствуйте, мне нужен был секундомер того, сколько я нахожусь в игре. Я наткнулся на темку с уже готовым, но он формата мин:сек.мсек. Т.е без часов. Я решил самостоятельно добавить часы, но у меня вышли кое какие траблы с этим. Часы считает нормально, но вот минуты идут выше 59. Как исправить, что добавить?
Lua:
local vk = require 'vkeys'
local timertime, reservetime, enabled, paused = 0, 0, false, false

function main()
    if not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do
    wait(0)
        if isKeyJustPressed(vk.VK_F2) then
            if enabled then
                if paused then
                    timertime = os.clock() - reservetime + timertime
                    reservetime = 0
                else
                    reservetime = os.clock()
                end
                paused = not paused
            else
                enabled = true
                timertime = os.clock()
            end
        end
        if isKeyJustPressed(vk.VK_F3) then
            timertime, reservetime, enabled, paused = 0, 0, false, false
        end
        if enabled and not paused then
            printStringNow(string.format("%02i:%06.3f", math.floor((os.clock() - timertime) / 60), os.clock() - timertime - math.floor((os.clock() - timertime) / 60) * 60), 5000)
        end
    end
end
Lua:
local vk = require 'vkeys'
local timertime, reservetime, enabled, paused = 0, 0, false, false

function main()
    if not isSampLoaded() then return end
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand("testtime2", function (arg)
        timertime = timertime + arg
    end)
    while true do
    wait(0)
        if isKeyJustPressed(vk.VK_F2) then
            if enabled then
                if paused then
                    timertime = os.clock() - reservetime + timertime
                    reservetime = 0
                else
                    reservetime = os.clock()
                end
                paused = not paused
            else
                enabled = true
                timertime = os.clock()
            end
        end
        if isKeyJustPressed(vk.VK_F3) then
            timertime, reservetime, enabled, paused = 0, 0, false, false
        end
        if enabled and not paused then
            local hours = math.floor((os.clock() - timertime) / 60 / 60)
            local minuts = math.floor((os.clock() - timertime) / 60)
            local second = os.clock() - timertime - math.floor((os.clock() - timertime) / 60) * 60
            printStringNow(string.format("%02i:%02i:%02i", hours,minuts,second), 5000)
        end
    end
end
Заранее спасибо =)
 

|DEVIL|

Известный
363
280
Изучил, но не нашёл там для себя ответа, ник выводится, только не мой а чужой. Можно ли сделать так, чтобы выводился именно мой ник или же человека который юзает скрипт?
 

Benya

Активный
145
45
Изучил, но не нашёл там для себя ответа, ник выводится, только не мой а чужой. Можно ли сделать так, чтобы выводился именно мой ник или же человека который юзает скрипт?
В сабже есть ответ на твой вопрос.
Получай свой ID, по нему получай уже ник

Lua:
local _, id = sampGetPlayerIdByCharHandle(PLAYER_PED) -- получить свой ид
local _, id = sampGetPlayerIdByCharHandle(ped) -- получить ид другого игрока. ped - это хендл персонажа
 
  • Нравится
Реакции: |DEVIL|

Quasper

Известный
835
354
Изучил, но не нашёл там для себя ответа, ник выводится, только не мой а чужой. Можно ли сделать так, чтобы выводился именно мой ник или же человека который юзает скрипт?
sampGetPlayerNickname(select(2, sampGetPlayerIdByCharHandle(playerPed))
 
  • Нравится
Реакции: HubbaBubbkin и |DEVIL|

Fabregoo

Известный
656
128
как перекинуть скрипт в lib что бы он работал как скрипт, маскировка скрипта типо...
То есть, есть скрипт TopCheat228 можно ли его перекинуть в lib что бы он работал как мунлоадере?
 

Musaigen

abobusnik
Проверенный
1,606
1,361
как перекинуть скрипт в lib что бы он работал как скрипт, маскировка скрипта типо...
То есть, есть скрипт TopCheat228 можно ли его перекинуть в lib что бы он работал как мунлоадере?
в каком нибудь другом файле import("lib/TopCheat228.lua")
 
  • Нравится
Реакции: Fabregoo

Rezistence

Участник
67
1
Lua:
local sMenuOpen = imgui.ImBool(false)

local rInfo = {
    state = false,
    sMenuOpen = 0
    }   

if rinfo.sMenuOpen.v then
        imgui.SetNextWindowSize(imgui.ImVec2(wx, wy))
        imgui.SetNextWindowPos(imgui.ImVec2(rx/2-wx/2, ry/2-wy/2))
        imgui.Begin("recon", _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoSavedSettings)
        imgui.End()
    end

function SE.onTogglePlayerSpectating(state)
    rInfo.state = state
  sMenuOpen.v = true
end

Почему при входе в recon не включает меню?
 

ufdhbi

Известный
Проверенный
1,459
866
Lua:
local sMenuOpen = imgui.ImBool(false)

local rInfo = {
    state = false,
    sMenuOpen = 0
    }  

if rinfo.sMenuOpen.v then
        imgui.SetNextWindowSize(imgui.ImVec2(wx, wy))
        imgui.SetNextWindowPos(imgui.ImVec2(rx/2-wx/2, ry/2-wy/2))
        imgui.Begin("recon", _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoSavedSettings)
        imgui.End()
    end

function SE.onTogglePlayerSpectating(state)
    rInfo.state = state
  sMenuOpen.v = true
end

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

Rezistence

Участник
67
1
логику в коде не соблюдаешь от слова совсем, кидай весь код а не обрывки и огрызки
Lua:
local imgui = require "imgui"
local key = require 'vkeys'
local mem = require "memory"
local SE = require 'lib.samp.events'
local sMenuOpen = imgui.ImBool(false)

local rx, ry = getScreenResolution()
local wx, wy = 800, 450


local rInfo = {
    state = false,
    sMenuOpen = 0
    }

function imgui.OnDrawFrame()
if sMenuOpen.v then
        imgui.SetNextWindowSize(imgui.ImVec2(wx, wy))
        imgui.SetNextWindowPos(imgui.ImVec2(rx/2-wx/2, ry/2-wy/2))
        imgui.Begin("recon", _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoSavedSettings)
        imgui.End()
    end
end

function SE.onTogglePlayerSpectating(state)
    rInfo.state = state
  sMenuOpen.v = true
end

Что ещё нужно?
 

ufdhbi

Известный
Проверенный
1,459
866
Lua:
local imgui = require "imgui"
local key = require 'vkeys'
local mem = require "memory"
local SE = require 'lib.samp.events'
local sMenuOpen = imgui.ImBool(false)

local rx, ry = getScreenResolution()
local wx, wy = 800, 450


local rInfo = {
    state = false,
    sMenuOpen = 0
    }

function imgui.OnDrawFrame()
if sMenuOpen.v then
        imgui.SetNextWindowSize(imgui.ImVec2(wx, wy))
        imgui.SetNextWindowPos(imgui.ImVec2(rx/2-wx/2, ry/2-wy/2))
        imgui.Begin("recon", _, imgui.WindowFlags.NoCollapse + imgui.WindowFlags.NoResize + imgui.WindowFlags.NoMove + imgui.WindowFlags.NoBringToFrontOnFocus + imgui.WindowFlags.NoTitleBar + imgui.WindowFlags.NoSavedSettings)
        imgui.End()
    end
end

function SE.onTogglePlayerSpectating(state)
    rInfo.state = state
  sMenuOpen.v = true
end

Что ещё нужно?
а где main?
 
  • Нравится
Реакции: Fabregoo

getsdfssdfsdfs

Участник
45
0
Lua:
local selected_lag = imgui.ImInt(0)
local flags_item = {'1R1', '1R2', '1R3'}

if imgui.Combo('1', selected_lag, flags_item, 3) then
    sampSendChat(selected_lag[flags_item.v + 0])
end

Ну что тут не так? При выборе одного из пунктов в комбо, крашит скрипт
 

ishi

Известный
493
110
Есть такой вот код, немного упрощающий читаемость кода (в теории)
Lua:
ped = function(thisped)
    local this = {}
    this.pos = function()
        return getCharCoordinates(thisped)
    end
    this.offset = function(x,y,z)
        return getOffsetFromCharInWorldCoords(thisped,x,y,z)
    end
    return this
end

ped(playerPed).pos() -- работает без нареканий, но вот
ped(playerPed).offset(0,35,0) -- уже не радует: в контексте данной строки
Lua:
string.format("%.0f %.0f %.0f\n%.0f %.0f %.0f",ped(playerPed).pos(),ped(playerPed).offset(0,35,0))
выдаёт ошибку bad argument #6 (no value).
Понять не могу, где ошибся. Может быть, "классы" на луа строятся иначе?
 

ufdhbi

Известный
Проверенный
1,459
866
Есть такой вот код, немного упрощающий читаемость кода (в теории)
Lua:
ped = function(thisped)
    local this = {}
    this.pos = function()
        return getCharCoordinates(thisped)
    end
    this.offset = function(x,y,z)
        return getOffsetFromCharInWorldCoords(thisped,x,y,z)
    end
    return this
end

ped(playerPed).pos() -- работает без нареканий, но вот
ped(playerPed).offset(0,35,0) -- уже не радует: в контексте данной строки
Lua:
string.format("%.0f %.0f %.0f\n%.0f %.0f %.0f",ped(playerPed).pos(),ped(playerPed).offset(0,35,0))
выдаёт ошибку bad argument #6 (no value).
Понять не могу, где ошибся. Может быть, "классы" на луа строятся иначе?
Вот пример класса лога
Lua:
local log = {}

function log:new(set)
    
    local obj = {
        path = set.path,
        fileName = set.name
    }

    function obj:write(text)
        local f = io.open(self.path .. self.fileName, 'a')
        if f then f:write(text .. "\n") f:close() end
    end

    function obj:clear(text)
        local f = io.open(self.path .. self.fileName, 'w+')
        if f then f:write('') f:close() end
    end
    
    function obj:remove(text)
        os.remove(self.path .. self.fileName)
    end

    setmetatable(obj, self)
    self.__index = self

    return obj
end

miniLog = log:new {path = '', name = 'Hello.log'}

miniLog:write('Hello world')
 
  • Нравится
Реакции: Quasper и ishi