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

Удалённый пользователь 341712

Гость
какой хук не даст меня выкинуть из машины серверу?
 

GAuditore

Активный
131
29
Lua:
script_name('Input Helper')
script_version_number(1)
script_moonloader(020)
script_author('DonHomka')
script_description('Help to game in samp :)')

local ffi = require("ffi")
require 'lib.moonloader'
require 'lib.sampfuncs'
local mem = require "memory"
ffi.cdef[[
    short GetKeyState(int nVirtKey);
    bool GetKeyboardLayoutNameA(char* pwszKLID);
    int GetLocaleInfoA(int Locale, int LCType, char* lpLCData, int cchData);
]]
local BuffSize = 32
local KeyboardLayoutName = ffi.new("char[?]", BuffSize)
local LocalInfo = ffi.new("char[?]", BuffSize)
chars = {
    ["й"] = "q", ["ц"] = "w", ["у"] = "e", ["к"] = "r", ["е"] = "t", ["н"] = "y", ["г"] = "u", ["ш"] = "i", ["щ"] = "o", ["з"] = "p", ["х"] = "[", ["ъ"] = "]", ["ф"] = "a",
    ["ы"] = "s", ["в"] = "d", ["а"] = "f", ["п"] = "g", ["р"] = "h", ["о"] = "j", ["л"] = "k", ["д"] = "l", ["ж"] = ";", ["э"] = "'", ["я"] = "z", ["ч"] = "x", ["с"] = "c", ["м"] = "v",
    ["и"] = "b", ["т"] = "n", ["ь"] = "m", ["б"] = ",", ["ю"] = ".", ["Й"] = "Q", ["Ц"] = "W", ["У"] = "E", ["К"] = "R", ["Е"] = "T", ["Н"] = "Y", ["Г"] = "U", ["Ш"] = "I",
    ["Щ"] = "O", ["З"] = "P", ["Х"] = "{", ["Ъ"] = "}", ["Ф"] = "A", ["Ы"] = "S", ["В"] = "D", ["А"] = "F", ["П"] = "G", ["Р"] = "H", ["О"] = "J", ["Л"] = "K", ["Д"] = "L",
    ["Ж"] = ":", ["Э"] = "\"", ["Я"] = "Z", ["Ч"] = "X", ["С"] = "C", ["М"] = "V", ["И"] = "B", ["Т"] = "N", ["Ь"] = "M", ["Б"] = "<", ["Ю"] = ">"
}


function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then
        return
    end
    while not isSampAvailable() do wait(100) end

    inputHelpText = renderCreateFont("Arial", 9, FCR_BORDER + FCR_BOLD)
    lua_thread.create(inputChat)
    lua_thread.create(showInputHelp)

    while true do
        wait(0)
        if isSampfuncsConsoleActive and sampIsChatInputActive then
            sampSetChatInputEnabled(false)
        end
        if(isKeyDown(VK_T) and wasKeyPressed(VK_T))then
            if(not sampIsChatInputActive() and not sampIsDialogActive())then
                sampSetChatInputEnabled(true)
            end
        end
    end
    wait(-1)
end

function showInputHelp()
    while true do
        local chat = sampIsChatInputActive()
        if chat == true then
            local in1 = sampGetInputInfoPtr()
            local in1 = getStructElement(in1, 0x8, 4)
            local in2 = getStructElement(in1, 0x8, 4)
            local in3 = getStructElement(in1, 0xC, 4)
            fib = in3 + 41
            fib2 = in2 + 10
            local _, pID = sampGetPlayerIdByCharHandle(playerPed)
            local name = sampGetPlayerNickname(pID)
            local score = sampGetPlayerScore(pID)
            local color = sampGetPlayerColor(pID)
            local capsState = ffi.C.GetKeyState(20)
            local success = ffi.C.GetKeyboardLayoutNameA(KeyboardLayoutName)
            local errorCode = ffi.C.GetLocaleInfoA(tonumber(ffi.string(KeyboardLayoutName), 16), 0x00000002, LocalInfo, BuffSize)
            local localName = ffi.string(LocalInfo)
            local text = string.format(
                "%s :: {%0.6x}%s[%d] {ffffff}:: Капс: %s {FFFFFF}:: Язык: {ffeeaa}%s{ffffff}",
                os.date("%H:%M:%S"), bit.band(color,0xffffff), name, pID, getStrByState(capsState), string.match(localName, "([^%(]*)")
            )
            renderFontDrawText(inputHelpText, text, fib2, fib, 0xD7FFFFFF)
            end
        wait(0)
    end
end
function getStrByState(keyState)
    if keyState == 0 then
        return "{ffeeaa}Выкл{ffffff}"
    end
    return "{9EC73D}Вкл{ffffff}"
end
function translite(text)
    for k, v in pairs(chars) do
        text = string.gsub(text, k, v)
    end
    return text
end

function inputChat()
    while true do
        if(sampIsChatInputActive())then
            local getInput = sampGetChatInputText()
            if(oldText ~= getInput and #getInput > 0)then
                local firstChar = string.sub(getInput, 1, 1)
                if(firstChar == "." or firstChar == "/")then
                    local cmd, text = string.match(getInput, "^([^ ]+)(.*)")
                    local nText = "/" .. translite(string.sub(cmd, 2)) .. text
                    local chatInfoPtr = sampGetInputInfoPtr()
                    local chatBoxInfo = getStructElement(chatInfoPtr, 0x8, 4)
                    local lastPos = mem.getint8(chatBoxInfo + 0x11E)
                    sampSetChatInputText(nText)
                    mem.setint8(chatBoxInfo + 0x11E, lastPos)
                    mem.setint8(chatBoxInfo + 0x119, lastPos)
                    oldText = nText
                end
            end
        end
        wait(0)
    end
end
в цикл (while true do wait(0) *код* endfunction main()
 
У

Удалённый пользователь 341712

Гость
Возможно сервер еще SetPlayerPos делает
неа, сделал, я дал команду серверу меня выкинуть - выкинуло
Lua:
require 'lib.moonloader'
local samp = require 'lib.samp.events'
local status = false
function main()
    while not isSampLoaded() do wait(0) end
    sampRegisterChatCommand('using', function()
        status = not status
        sampAddChatMessage((status and "Включено" or "Выключено"), 0xFFFFFFFF)
    end)
    while true do
        wait(0)
    end
end

function samp.onRemovePlayerFromVehicle()
    if status then
        return false
    end
end

function samp.onSetPlayerPos()
    if status then
        return false
    end
end
 

chockscrot

Участник
42
1
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(10) end
    requestAnimation("POOL") -- download file with animations "POOL"
    sampRegisterChatCommand('aroundanim', aroundanim)
    while true do
    wait(0)
    end
end

function aroundanim()
    for k, char in pairs(getAllChars()) do
    if char ~= PLAYER_PED then
    taskPlayAnim(char, "POOL_XLONG_SHOT", "POOL", 4.0, false, false, false, false, -1) -- you can use any animations, just download it at the beginning function, also you can add arg in command and download animation from it
--taskPlayAnim (playerped, name animation, file animation, speed anim, bool loop anim, bool lock posX, bool lock posY, bool return to start position, time playing (-1 to play from start to end))
    end
    end
end
here is all animation list: https://sampwiki.blast.hk/wiki/Animations
well they are doing the animation in a matter of seconds and stopping, I want you to do the animation and continue, just stop the animation if you disable it with the command
 

BARRY BRADLEY

Известный
711
176
Как сделать такую обводку (заливку) района либо территории (координаты есть). Нужно залить либо район либо территорию по координатах, можно без флажка, просто как?

sa-mp-026.png
 

Prodovecvirtov

Новичок
3
0
ПОЧЕМУ НЕ РАБОТАЕТ
Код:
require 'lib.moonloader'
function main()
    sampRegisterChatCommand('gmc', cmd_gm)
    sampRegisterChatCommand('fixcar', cmd_fix)
    sampRegisterChatCommand('collis', cmd_col)
    wait(-1)
end
function cmd_gm()
        a = storeCarCharIsInNoSave(PLAYER_PED)
setCarProofs(a, true, true, true, true, true)
end
function cmd_fix()
        b = storeCarCharIsInNoSave(PLAYER_PED)
fixCar(b)
end
function cmd_col()
    c = storeCarCharIsInNoSave(PLAYER_PED)
    setCarCollision(c, j)
    sampAddChatMessage(tostring(j), 0x4682B4)
end
 

wulfandr

Известный
637
260
ПОЧЕМУ НЕ РАБОТАЕТ
Код:
require 'lib.moonloader'
function main()
    sampRegisterChatCommand('gmc', cmd_gm)
    sampRegisterChatCommand('fixcar', cmd_fix)
    sampRegisterChatCommand('collis', cmd_col)
    wait(-1)
end
function cmd_gm()
        a = storeCarCharIsInNoSave(PLAYER_PED)
setCarProofs(a, true, true, true, true, true)
end
function cmd_fix()
        b = storeCarCharIsInNoSave(PLAYER_PED)
fixCar(b)
end
function cmd_col()
    c = storeCarCharIsInNoSave(PLAYER_PED)
    setCarCollision(c, j)
    sampAddChatMessage(tostring(j), 0x4682B4)
end
лучше приведи аргументы почему должно работать. в след. раз выкладывай весь код, а не его отрезок
 

NoName_001

Участник
152
20
Перед какими символами нужно ставить % в text:find/text:match ?
/ ? . , < > ( ) { } ! + = - _ и так далее




Как в
Lua:
imgui.Text('FAQ')
if imgui.IsItemClicked() then
    imgui.LogToClipboard()
    imgui.LogText("--[[текст в imgui.text]]")
    imgui.LogFinish()
end
скопировать именно текст из imgui.text(текст может варьироваться варик с imgui.LogText("FAQ") не нужон)