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

James Saula

Известный
113
26
каким образом реализовать подобный поворот персонажа в прицеливании? не сенсой конечно
ped.fAimingRotation вертикаль
ped.pedIK.TorsoOrien[1] горизонталь
cam.vecAimingTargetCoors тож пробовал но что-то не(
фигня какая-то, будто нужно присваивать флаг какой-то чтобы он не сбивался своей же анимкой
Lua:
require "lib.moonloader"

local ffi = require "ffi"
local samemory = require "SAMemory.shared"
samemory.require 'CPed'

function main()
    while not isSampAvailable() do wait(100) end

    sampAddChatMessage("Скрипт загружен! Нажмите F4 для активации.", 0xFFFFAA00)

    local enabled = false
    local offset = 0.524
    local baseRot = nil

    while true do
        wait(0)

        -- Проверяем нажатие F4 (код 0x73)
        if isKeyJustPressed(0x73) then
            enabled = not enabled
            if enabled then
                sampAddChatMessage("Режим поворота включен.", 0x00FF00)
                local charPtr = getCharPointer(PLAYER_PED)
                if charPtr and charPtr ~= 0 then
                    local ped = ffi.cast("CPed*", charPtr)
                    baseRot = ped.fCurrentRotation
                end
            else
                sampAddChatMessage("Режим поворота выключен.", 0xFF0000)
                baseRot = nil
            end
        end

        if enabled then
            local charPtr = getCharPointer(PLAYER_PED)
            if charPtr and charPtr ~= 0 then
                local ped = ffi.cast("CPed*", charPtr)
                -- Проверяем, что персонаж стоит и не в машине
                if ped.nPedState == 1 and ped.pVehicle == nil then
                    if baseRot == nil then
                        baseRot = ped.fCurrentRotation
                    end
                    -- Поворачиваем всего персонажа
                    ped.fCurrentRotation = baseRot + offset
                    ped.fHeadingChangeRate = 0
                    ped.nPedFlags.bUpdateMatricesRequired = 1
                else
                    -- Если начал двигаться, выключаем режим
                    if baseRot ~= nil then
                        sampAddChatMessage("Режим отключен (движение/машина).", 0xFF0000)
                        enabled = false
                        baseRot = nil
                    end
                end
            end
        end
    end
end
бамп
 

Baklaxa

Участник
53
21
Есть ли сниппет функции, чтобы получить хэндл или ид объекта на котором персонаж стоит? isCharTouchingObject(Ped ped, Object object) не подходит
 

Baklaxa

Участник
53
21
почему альт таб не игнорируется?

addEventHandler("onWindowMessage", function(msg, wparam, lparam)
if msg == 0x12 and wparam == 0x9 then
consumeWindowMessage(true, true)
end
end)
 

k1nt3rr0

Участник
56
18
На арз в чате организаций есть 2 типа строк:
1:
[R] Ассистент шефа Nick_Name[288]: Text.
[R] [Head CPD] Ассистент шефа Nick_Name[288]: Text.
Помогите пожалуйста хукнуть эти две строки, мне нужно найти текст из них и записать в local.
Спасибо!
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,258
12,696
На арз в чате организаций есть 2 типа строк:
1:
[R] Ассистент шефа Nick_Name[288]: Text.
[R] [Head CPD] Ассистент шефа Nick_Name[288]: Text.
Помогите пожалуйста хукнуть эти две строки, мне нужно найти текст из них и записать в local.
Спасибо!
Lua:
--[R] Ассистент шефа Nick_Name[288]: Text.
local rankName, name, id,  message = text:match("%[R%] (.+) (%w+_%w+)%[(%d+)%]: (.+)")

--[R] [Head CPD] Ассистент шефа Nick_Name[288]: Text.
local rankName1, rankName2, name, id, message = text:match("%[R%] %[(.+)%] (.+) (%w+_%w+)%[(%d+)%]: (.+)")
 
  • Влюблен
Реакции: k1nt3rr0

Baklaxa

Участник
53
21
как отправить урон битой по транспорту?

~нанесение урона холодным оружием транспорту
 

fanfarik

Новичок
11
2
как сделать серверное нажатие клавиши? мне нужно стрелочки нажать, чтобы текстдрав обработал, а они просто мне экран поворачивают:
function tapKey(key, delay)
setVirtualKeyDown(key, true)
wait(delay or 50)
setVirtualKeyDown(key, true)
end
function pressArrow(dir)
local keys = {
UP = 0x26,
DOWN = 0x28,
LEFT = 0x25,
RIGHT = 0x27
}
local key = keys[dir]
if not key then return end
lua_thread.create(function()
tapKey(key, 100)
end)
end
setGameKeyState делает тоже самое
 

chromiusj

Известный
Модератор
6,070
4,414
как сделать серверное нажатие клавиши? мне нужно стрелочки нажать, чтобы текстдрав обработал, а они просто мне экран поворачивают:
function tapKey(key, delay)
setVirtualKeyDown(key, true)
wait(delay or 50)
setVirtualKeyDown(key, true)
end
function pressArrow(dir)
local keys = {
UP = 0x26,
DOWN = 0x28,
LEFT = 0x25,
RIGHT = 0x27
}
local key = keys[dir]
if not key then return end
lua_thread.create(function()
tapKey(key, 100)
end)
end
setGameKeyState делает тоже самое
Вот тут посмотри как делается:
 

Joce

Известный
94
33
if INPUT_VAR_1_.text == "LD_BEAT:up" then
--jump to 0022 (if previous if statement is false) --0022 JMP-JMP
var_2_3 = 1 --var_2_3 NUMBER-NUMBER
until false or (previous if statement is true) --location 0019
var_2_4 = -128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0022--0022 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:down" then
--jump to 0030 (if previous if statement is false) --0030 JMP-JMP
var_2_3 = 1 --var_2_3 NUMBER-NUMBER
var_2_4 = 128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0030--0030 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:right" then
--jump to 0038 (if previous if statement is false) --0038 JMP-JMP
until false or (previous if statement is true) --location 0033
var_2_3 = 0 --var_2_3 NUMBER-NUMBER
var_2_4 = 128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0038--0038 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:left" then
--jump to 0045 (if previous if statement is false) --0045 JMP-JMP
var_2_3 = 0 --var_2_3 NUMBER-NUMBER
var_2_4 = -128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
end
end
end
end
если я правильно понял, оно просто нажимает кнопки через setGameKeyState, но в моем коде для грузчика на evolve он не работал, даже с 700 мс задержки(
ну конечно, ты же декомп юзаешь какой-то говнястый
 

chromiusj

Известный
Модератор
6,070
4,414
if INPUT_VAR_1_.text == "LD_BEAT:up" then
--jump to 0022 (if previous if statement is false) --0022 JMP-JMP
var_2_3 = 1 --var_2_3 NUMBER-NUMBER
until false or (previous if statement is true) --location 0019
var_2_4 = -128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0022--0022 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:down" then
--jump to 0030 (if previous if statement is false) --0030 JMP-JMP
var_2_3 = 1 --var_2_3 NUMBER-NUMBER
var_2_4 = 128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0030--0030 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:right" then
--jump to 0038 (if previous if statement is false) --0038 JMP-JMP
until false or (previous if statement is true) --location 0033
var_2_3 = 0 --var_2_3 NUMBER-NUMBER
var_2_4 = 128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
else
--location 0038--0038 LOCATION-LOCATION_
if INPUT_VAR_1_.text == "LD_BEAT:left" then
--jump to 0045 (if previous if statement is false) --0045 JMP-JMP
var_2_3 = 0 --var_2_3 NUMBER-NUMBER
var_2_4 = -128 --var_2_4 NUMBER-NUMBER
setGameKeyState(var_2_3, var_2_4)
end
end
end
end
спасибо, я понял как это работает
function tapKey(key, delay)
setGameKeyState(key[1], key[2])
wait(delay or 50)
setGameKeyState(key[1], 0)
end
function pressArrow(dir)
local keys = {
UP = {1, -128},
DOWN = {1, 128},
LEFT = {0, -128},
RIGHT = {0, 128}
}
local key = keys[dir:upper()]
if not key then return end
lua_thread.create(function()
tapKey(key, 100)
end)
end
Ну блин, я не буду называть это скилл ишью, и подобными обидными словами, но в наше время это уже решает простым же тыком в всякий нейрокальный чат:

Lua:
script_name("ArizonaDancerByKraft1k")
script_author("kraft1k")
script_version("v1.0")

local event = require("samp.events")
local dancer = false

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

    if doesFileExist("moonloader\\ArizonaDancerByKraft1k.luac") then
        while not sampIsLocalPlayerSpawned() do
            wait(0)
        end

        sampRegisterChatCommand(
            "dancer",
            function()
                dancer = not dancer
                printStringNow(
                    ("~w~[~r~DANCER ~w~by ~g~Kraft1k ~w~for ~l~BLAST~w~.~b~HK~w~] ~%s~%s"):format(
                        dancer and "g" or "r",
                        dancer and "ON" or "OFF"
                    ),
                    4000
                )
            end
        )

        wait(2000)
        sampAddChatMessage(
            "[{cd3030}Arizona-RP Dancer{FFFFFF}] {43A8B9}Lua {FFFFFF}by {00DD00}Kraft1k {FFFFFF}for {484d50}BLAST{FFFFFF}.{0095ca}HK",
            -1
        )
        sampAddChatMessage(
            "[{cd3030}Arizona-RP Dancer{FFFFFF}] {00DD00}Включить {FFFFFF}/ {cd3030}Выключить {FFFFFF}- {0095ca}/DANCER",
            -1
        )
    else
        sampAddChatMessage(
            "[{cd3030}Arizona-RP Dancer{FFFFFF}] {43A8B9}Скрипт был переименован, верните прежнее название - {484d50}ArizonaDancerByKraft1k.luac",
            -1
        )
    end
    wait(-1)
end

function event.onShowTextDraw(textdraw, data)
    if dancer and data.position.x >= 303.4 and data.position.x <= 324.6 then
        if data.text == "LD_BEAT:up" then
            setGameKeyState(1, -128)
        elseif data.text == "LD_BEAT:down" then
            setGameKeyState(1, 128)
        elseif data.text == "LD_BEAT:right" then
            setGameKeyState(0, 128)
        elseif data.text == "LD_BEAT:left" then
            setGameKeyState(0, -128)
        end
    end
end