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

Garrus

Известный
159
20
Подскажите, как можно изменить кодировку строки из ANSI в UTF-8 для последующей отправки через GET-запрос?
Нашел функцию, но что-то она не работает - на выходе пустая строка.
Lua:
ffi.cdef[[
    int MultiByteToWideChar(unsigned int CodePage, unsigned int dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr, int cchWideChar);              
    int WideCharToMultiByte(unsigned int CodePage, unsigned int dwFlags, wchar_t* lpWideCharStr, int cchWideChar, char* lpMultiByteStr, int cbMultiByte, char* lpDefaultChar, int* lpUsedDefaultChar);
]]

function ansitoutf8(str)
local widestr = ffi.new("wchar_t[?]", 1024)
local utf8str = ffi.new("char[?]",    1024)
local useddc  = ffi.new("int[?]",        1)

ffi.C.MultiByteToWideChar(1251, 0, str, #str, widestr, 1024)
ffi.C.WideCharToMultiByte(65001, 0, widestr, -1, utf8str, 1024, nil, useddc)

return ffi.string(utf8str)    
end
 
Последнее редактирование:

Thomas_Johnson

Известный
Проверенный
183
21
Есть ли вариант изменить дальность появления зеленого треугольника над головой, когда ПКМ нажимаешь без оружия?
 

san0

Известный
Друг
411
267
Есть ли вариант изменить дальность появления зеленого треугольника над головой, когда ПКМ нажимаешь без оружия?
Как видно из комментария, только для кулака. Стандартное значение 10.0, я поставил 0.5
Lua:
require "lib.moonloader"
local memory = require "memory"

kWeaponDatStart = 0xC8AAB8
kWeaponID = 0x0                         -- branch
kMeleeSkill = 0x0                     -- std
kBlockSize = 0x70
kTargetRangeOffset = 0x4


function main()
    while true
    do
        wait(0)
        if isOpcodesAvailable() and isSampAvailable() 
        then
            memory.setfloat(
                kWeaponDatStart + (kWeaponID + kMeleeSkill) * kBlockSize + kTargetRangeOffset, 
                0.5, false)
            local scr = thisScript()
            scr:unload()
        end
    end
end
 
  • Нравится
Реакции: Thomas_Johnson

Thomas_Johnson

Известный
Проверенный
183
21
Возможно ли подключить LuaSocket?
Библиотеки (https://www.blast.hk/threads/16031/)

Пишет ошибку в string.format'e, что ему приходит строка во втором аргументе, а не число(что очень странно), если ставлю tonumber(sTime), пишет, что приходит nil, а не число, куда тыкаться?
Lua:
function stimer( sTime )
    if timer then
        timer = false
        sampAddChatMessage(' Timer was disabled', 0x3399FF)
    else
        if string.match( sTime, "(%d+)m" ) then
            local sTime = string.find( sTime, "(%d+)m" )
            sTime = tonumber(sTime) * 60
            timeFormat = 'm'
        elseif string.match( sTime, "(%d+)h" ) then
            local sTime = string.find( sTime, "(%d+)h" )
            sTime = tonumber(sTime) * 360
            timeFormat = 'h'
        elseif string.match( sTime, "(%d+)s" ) then
            local sTime = string.find( sTime, "(%d+)s" )
            sTime = tonumber(sTime)
            timeFormat = 's'
        else
            sampAddChatMessage(' Wrong argument, use \'/stimer [time]s/m/h\'', 0x3399FF)
            return false
        end
        timer = true
        sampAddChatMessage( string.format(' Timer will alarm in %d%s', sTime, timeFormat), 0x3399FF)
        period = os.time + sTime
    end 
end
 
Последнее редактирование модератором:
  • Нравится
Реакции: NARVELL

itsLegend

Фонд борьбы за жуков 🐞
Администратор
2,695
1,448
Видимость объявленных локальных переменных внутри if осуществляется только до следующего elseif/else/end. Это правило применимо так же и к циклу и другим подобным блокам (функция...).
И некорректно объявлять уже объявленную и заданную переменную
 
  • Нравится
Реакции: Thomas_Johnson

XeuTep

Новичок
75
8
Подскажите пожалуйста, с какой программой создаются Луа скрипты? Санни Буилдер подойдёт?
 

Thomas_Johnson

Известный
Проверенный
183
21
Как сделать клиентский 3д текст как /dl, чтобы неограниченное кол-во можно было их клепать
 

MISTER_GONWIK

Всефорумный гонщик
Всефорумный модератор
1,260
1,737
Как сделать клиентский 3д текст как /dl, чтобы неограниченное кол-во можно было их клепать
берешь позицию -> конвертируешь из 3D в 2D -> рисуешь текст на экране по этим координатам -> профит