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

dameoff

Участник
70
9
в плане обойти систему? сказали же, если работа с памятью присутствует, то надо искать новые адреса
представим, у тебя очень хитрый скрипт, с выводом в чат не через sampAddChatMessage, а значит ты используешь адреса:
на р1 он такой: samp_base + 0x645A0)
Посмотреть вложение 271163
но на р3 же что то да добавили, можно посмотреть в идбшках и сравнить через bindiff (либо почитать в архивах калкора что там нового):
адрес на р3: samp_base + 0x679F0
271164


лучше сам покажи, что у тебя там такое, чтоб меньше непониманий было
Спасибо , что изъяснил , пока что нет проектов каких-то просто с начало бы хотелось знать чо за темка , так сказать подшарить , подШпионироГолубинить, спасибо

 
Последнее редактирование:
  • Эм
Реакции: Black_Cow и Winstаl

Oleg1337228

Участник
377
18
помогите пожалуйста с этим скриптом как сделать чтобы я мог иметь 2-3 этих скрипта чтобы спавнить по несколько ботов для тренировки стрельбы и чтобы эти скрипты юзали разные конфиги, а то даже если я делаю 2 скрипта меняю комманду они всеравно юзают 1 конфиг и я не могу создать 2 бота. Заранее спасибо!
 

Вложения

  • dmx.lua
    11.1 KB · Просмотры: 1

dmitry.karle

Известный
367
103
помогите пожалуйста с этим скриптом как сделать чтобы я мог иметь 2-3 этих скрипта чтобы спавнить по несколько ботов для тренировки стрельбы и чтобы эти скрипты юзали разные конфиги, а то даже если я делаю 2 скрипта меняю комманду они всеравно юзают 1 конфиг и я не могу создать 2 бота. Заранее спасибо!
через кфг сделай или просто через таблицу если не надо

Lua:
cfg = ini.load({
    main = {
        id = 24,
        dmg = true,
        hp = 300,
        etext = '~g~DAMAGE',
        mb = false,
        fox = false,
        dmf = false,
        hdshot = true,
        bot_count = 1 -- количество ботяр
    }
}, "DMX")

-- таблица для хранения ботов
local bots = {}
local bot_blips = {}

function main()
    if not isSampfuncsLoaded() or not isSampLoaded() then return end
    repeat wait(0) until isSampAvailable()
    sampRegisterChatCommand('dmx.menu', menu)
    sampRegisterChatCommand('dmx.bots', function() -- Добавлена команда для управления ботами
        sampShowDialog(555, 'Управление ботами', string.format([[
        Количество ботов: {00ff00}%d
        Увеличить количество
        Уменьшить количество
        Пересоздать ботов]], cfg.main.bot_count), 'Выбрать', 'Закрыть', 2)
    end)
    sampAddChatMessage('{A30008}DMX || Тренировка стрельбы: {FF000D}    /dmx.menu', 0x580004)
    sampAddChatMessage('{A30008}DMX || Управление ботами: {FF000D}    /dmx.bots', 0x580004)
  
    while true do
        wait(0)
        -- штуку дуку с диалогами оставь свою
      
        -- диалог с ботярами
        local result, button, list, _ = sampHasDialogRespond(555)
        if result and button == 1 then
            if list == 0 then
                cfg.main.bot_count = math.min(cfg.main.bot_count + 1, 10) -- max 10 ботов
                ini.save(cfg, 'DMX')
                recreate_bots()
            elseif list == 1 then
                cfg.main.bot_count = math.max(cfg.main.bot_count - 1, 1) -- min 1 бот
                ini.save(cfg, 'DMX')
                recreate_bots()
            elseif list == 2 then
                recreate_bots()
            end
        end
        if activ == true then
            if isCharShooting(PLAYER_PED) then
                shoot = shoot + 1
                sampTextdrawSetString(2, 'SHOTS '..shoot)
            end
            for i, bot in ipairs(bots) do
                if doesCharExist(bot) then
                    if hasCharBeenDamagedByChar(bot, PLAYER_PED) then
                        if cfg.main.dmg == true then
                            printStyledString(cfg.main.etext, 333, 5)
                        end
                        popal = popal + 1
                        clearCharLastDamageEntity(bot)
                        sampTextdrawSetString(1, 'HIT '..popal)
                    end
                    if cfg.main.mb == true then
                        if isCharOnScreen(bot) then
                            local health = getCharHealth(bot)
                            local bx, by, bz = getCharCoordinates(bot)
                            local sx, sy = convert3DCoordsToScreen(bx, by, bz)
                            renderFontDrawText(font, 'HP:{00ffff} '..health, sx, sy, 0xffff0000)
                        end
                    end
                    if cfg.main.fox == true then
                        local px, py, pz = getCharCoordinates(PLAYER_PED)
                        local tx = px + math.random(-100,100)
                        local ty = py + math.random(-100,100)
                        local tz = getGroundZFor3dCoord(tx, ty, pz)
                        taskGoStraightToCoord(bot, tx, ty, tz, 6, 4000)
                    end
                    if cfg.main.dmf == true and isCharOnScreen(bot) then
                        local hxe = getCharHealth(bot)
                        local xaax, yaay, zaaz = getCharCoordinates(bot)
                        local boolshit, hpdamage = damag(hxe)
                        if boolshit then
                            kakat(hpdamage, xaax, yaay, zaaz)
                        end
                    end
                    -- чек анимок/здоровья
                    for k = 1, #anims do
                        if isCharPlayingAnim(bot, anims[k]) then
                            stopCharFacialTalk(bot)
                            clearCharTasks(bot)
                            clearLookAt(bot)
                            clearCharTasksImmediately(bot)
                        end
                    end
                    if getCharHealth(bot) <= 0 or isCharDead(bot) then
                        deleteChar(bot)
                        removeBlip(bot_blips[i])
                        table.remove(bots, i)
                        table.remove(bot_blips, i)
                        break
                    end
                    local bx, by, bz = getCharCoordinates(bot)
                    setBlipCoordinates(bot_blips[i], bx, by, bz)
                end
            end
            -- создание новых ботяр
            if #bots < cfg.main.bot_count then
                create_bot()
            end
            -- ботяры мертвы
            if #bots == 0 then
                recreate_bots()
            end
        end
    end
end

function create_bot() -- функция для создания бота
    local xx, yy, zz = getCharCoordinates(PLAYER_PED)
    zz = zz + 5.0
    local xxx = xx + math.random(-20,20)
    local yyy = yy + math.random(-20,20)
    local zzz = getGroundZFor3dCoord(xxx, yyy, zz)
    requestModel(301) -- моделька ped
    loadAllModelsNow()
    local new_bot = createChar(6, 301, xxx, yyy, zzz)
    markModelAsNoLongerNeeded(301)
    setCharHealth(new_bot, cfg.main.hp)
    local new_blip = addBlipForCoord(xxx, yyy, zzz)
    changeBlipColour(new_blip, 0xFF0000FF)
    setEveryoneIgnorePlayer(PLAYER_HANDLE, true)
    freezeCharPosition(new_bot, not cfg.main.fox)
    setCharSuffersCriticalHits(new_bot, cfg.main.hdshot)
    table.insert(bots, new_bot)
    table.insert(bot_blips, new_blip)
    return new_bot
end

function recreate_bots() --функа для пересоздания
    for i, bot in ipairs(bots) do --удаляем старых ботов
        if doesCharExist(bot) then
            deleteChar(bot)
        end
        if doesBlipExist(bot_blips[i]) then
            removeBlip(bot_blips[i])
        end
    end
    bots = {}
    bot_blips = {}
    -- создаём новых ботов
    for i = 1, cfg.main.bot_count do
        create_bot()
        wait(100)
    end
end

function act() --основная функция
    activ = not activ
    if activ == true then
        x, y, z = getCharCoordinates(PLAYER_PED)
        addgun()
        shoot = 0
        popal = 0
        sampTextdrawCreate(1, 'HIT '..popal, 50, 300)
        sampTextdrawSetAlign(1, 2)
        sampTextdrawCreate(2, 'SHOTS '..shoot, 75, 300)
        sampTextdrawSetAlign(2, 2)
        recreate_bots() -- создание ботов
    else
        -- удаление всех ботов после перезагрузки
        for i, bot in ipairs(bots) do
            if doesCharExist(bot) then
                deleteChar(bot)
            end
            if doesBlipExist(bot_blips[i]) then
                removeBlip(bot_blips[i])
            end
        end
        bots = {}
        bot_blips = {}
        removeAllCharWeapons(PLAYER_PED)
        setCharCoordinates(PLAYER_PED, x, y, z)
        sampTextdrawDelete(1)
        sampTextdrawDelete(2)
    end
    sampAddChatMessage('{A30008}DMX by Scrix {FF000D}'..(activ and '[Включен] для остальных игроков вы АФК' or '[Выключен] вы снова в игре'), 0x580004)
end

проверь, сам не проверял (добавь это в ту луашку просто)
 

tryboyobvitalya2007

Новичок
11
0
Ребят, вопрос есть. Мне нужно отключить весь CEF худ на аризоне на 10 секунд, а потом включить его обратно. Подскажите, это можно сделать? Знаю, что можно отключить его в принципе, но после этого его не подрубишь без релога. Заранее благодарю, накину плюсов за помощь. Спасибо.
 

Lance_Sterling

Известный
1,005
365
Ребят, вопрос есть. Мне нужно отключить весь CEF худ на аризоне на 10 секунд, а потом включить его обратно. Подскажите, это можно сделать? Знаю, что можно отключить его в принципе, но после этого его не подрубишь без релога. Заранее благодарю, накину плюсов за помощь. Спасибо.
Можно эмулировать получение изменения прозрачности на все элементы страницы
 
  • Клоун
Реакции: chapo

chapo

tg/inst: @moujeek
Всефорумный модератор
9,127
12,254
Ребят, вопрос есть. Мне нужно отключить весь CEF худ на аризоне на 10 секунд, а потом включить его обратно. Подскажите, это можно сделать? Знаю, что можно отключить его в принципе, но после этого его не подрубишь без релога. Заранее благодарю, накину плюсов за помощь. Спасибо.
Запихни это в эмуляцию цефовского пакета, должно сработать
JavaScript:
document.body.style.display = 'none' // скрыть
document.body.style.display = 'block' // показать
 
  • Нравится
Реакции: tryboyobvitalya2007

Naito

Активный
165
36
why does this happen?

[ML] (error) PlayerInfo: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'getCharPlayerIsTargeting'
...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:29: in function 'mehhh'
...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:17: in function <...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:14>
[ML] (error) PlayerInfo: Script died due to an error. (286F2464)
 

Winstаl

Известный
903
358
why does this happen?

[ML] (error) PlayerInfo: cannot resume non-suspended coroutine
stack traceback:
[C]: in function 'getCharPlayerIsTargeting'
...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:29: in function 'mehhh'
...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:17: in function <...al\Desktop\Naito\Aportes Tests\GTA Cry\moonloader\t2.lua:14>
[ML] (error) PlayerInfo: Script died due to an error. (286F2464)
There may be many reasons for this. Show the code of the function.
 
  • Нравится
Реакции: Naito

Naito

Активный
165
36
There may be many reasons for this. Show the code of the function.
Ohh, ok
code:
require "moonloader"
require "sampfuncs"

local lt = nil

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

function d()
    local r, p = getCharPlayerIsTargeting(PLAYER_PED)
    
    if r and p then
        if doesCharExist(p) then
            local i = sampGetPlayerIdByCharHandle(p)
            
            if i and i ~= -1 and sampIsPlayerConnected(i) then
                if lt ~= i then
                    local n = sampGetPlayerNickname(i)
                    sampAddChatMessage("aim: " .. n, 0x00FF00)
                    lt = i
                end
            end
        end
    else
        lt = nil
    end
end
 

Winstаl

Известный
903
358
1. getCharPlayerIsTargeting(PLAYER_HANDLE)
2. local i = sampGetPlayerIdByCharHandle(p) local result, i = sampGetPlayerIdByCharHandle(p) or
local i = select(2, sampGetPlayerIdByCharHandle(p))

1749499448994.png



lua:
function d()
    local r, p = getCharPlayerIsTargeting(PLAYER_HANDLE)
    if r and p then
        if doesCharExist(p) then
            local res, i = sampGetPlayerIdByCharHandle(p)
            
            if res and i ~= -1 and sampIsPlayerConnected(i) then
                if lt ~= i then
                    local n = sampGetPlayerNickname(i)
                    sampAddChatMessage("aim: " .. n, 0x00FF00)
                    lt = i
                end
            end
        end
    else
        lt = nil
    end
end
 
  • Вау
Реакции: Naito

Naito

Активный
165
36
1. getCharPlayerIsTargeting(PLAYER_HANDLE)
2. local i = sampGetPlayerIdByCharHandle(p) local result, i = sampGetPlayerIdByCharHandle(p) or
local i = select(2, sampGetPlayerIdByCharHandle(p))

Посмотреть вложение 272023


lua:
function d()
    local r, p = getCharPlayerIsTargeting(PLAYER_HANDLE)
    if r and p then
        if doesCharExist(p) then
            local res, i = sampGetPlayerIdByCharHandle(p)
           
            if res and i ~= -1 and sampIsPlayerConnected(i) then
                if lt ~= i then
                    local n = sampGetPlayerNickname(i)
                    sampAddChatMessage("aim: " .. n, 0x00FF00)
                    lt = i
                end
            end
        end
    else
        lt = nil
    end
end
thx bro
 
  • Нравится
Реакции: Winstаl

Dericode

Новичок
3
0
Можно ли создать скрипт, который при достижении координат пишет заданную команду?
Очень нужно, не сильно понимаю про это, а точнее про то как построить структуру скрипта.
 

Masayuki

Участник
82
33
Можно ли создать скрипт, который при достижении координат пишет заданную команду?
Очень нужно, не сильно понимаю про это, а точнее про то как построить структуру скрипта.
local x, y, z = getCharCoordinates(PLAYER_PED)
local distance = getDistanceBetweenCoords3d(координаты нужной точки, x, y, z)
if distance <= 2 then
sampSendChat('/time')
end
 

chapo

tg/inst: @moujeek
Всефорумный модератор
9,127
12,254
Как нормально отобразить букву "Ф" в геймтексте или текстдраве? Вместо "Ф" отображается "?", с остальными буквами все нормально
Lua:
local function cyrillic(text)
    local convtbl = {[230]=155,[231]=159,[247]=164,[234]=107,[250]=144,[251]=168,[254]=171,[253]=170,[255]=172,[224]=97,[240]=112,[241]=99,[226]=162,[228]=154,[225]=151,[227]=153,[248]=165,[243]=121,[184]=101,[235]=158,[238]=111,[245]=120,[233]=157,[242]=166,[239]=163,[244]=63,[237]=174,[229]=101,[246]=36,[236]=175,[232]=156,[249]=161,[252]=169,[215]=141,[202]=75,[204]=77,[220]=146,[221]=147,[222]=148,[192]=65,[193]=128,[209]=67,[194]=139,[195]=130,[197]=69,[206]=79,[213]=88,[168]=69,[223]=149,[207]=140,[203]=135,[201]=133,[199]=136,[196]=131,[208]=80,[200]=133,[198]=132,[210]=143,[211]=89,[216]=142,[212]=129,[214]=137,[205]=72,[217]=138,[218]=167,[219]=145};
    local result = {};
    for i = 1, #text do
        local c = text:byte(i);
        result[i] = string.char(convtbl[c] or c);
    end
    return table.concat(result);
end

return function(text, time)
    local color = time < 3 and '~r~' or (time < 5 and '~y~' or '~g~');
    printStyledString(cyrillic(('%s~n~%s%d ~w~%s'):format(text, color, time, Utils.plural(time, 'секунда', 'секунды', 'секунд'))), 100, 6);
end
 

Willy4ka

вилличка
Модератор
618
940
Как нормально отобразить букву "Ф" в геймтексте или текстдраве? Вместо "Ф" отображается "?", с остальными буквами все нормально
Lua:
local function cyrillic(text)
    local convtbl = {[230]=155,[231]=159,[247]=164,[234]=107,[250]=144,[251]=168,[254]=171,[253]=170,[255]=172,[224]=97,[240]=112,[241]=99,[226]=162,[228]=154,[225]=151,[227]=153,[248]=165,[243]=121,[184]=101,[235]=158,[238]=111,[245]=120,[233]=157,[242]=166,[239]=163,[244]=63,[237]=174,[229]=101,[246]=36,[236]=175,[232]=156,[249]=161,[252]=169,[215]=141,[202]=75,[204]=77,[220]=146,[221]=147,[222]=148,[192]=65,[193]=128,[209]=67,[194]=139,[195]=130,[197]=69,[206]=79,[213]=88,[168]=69,[223]=149,[207]=140,[203]=135,[201]=133,[199]=136,[196]=131,[208]=80,[200]=133,[198]=132,[210]=143,[211]=89,[216]=142,[212]=129,[214]=137,[205]=72,[217]=138,[218]=167,[219]=145};
    local result = {};
    for i = 1, #text do
        local c = text:byte(i);
        result[i] = string.char(convtbl[c] or c);
    end
    return table.concat(result);
end

return function(text, time)
    local color = time < 3 and '~r~' or (time < 5 and '~y~' or '~g~');
    printStyledString(cyrillic(('%s~n~%s%d ~w~%s'):format(text, color, time, Utils.plural(time, 'секунда', 'секунды', 'секунд'))), 100, 6);
end
возможно это связано с этим
1749660468814.png
 
  • Грустно
Реакции: chapo