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

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Как можно это оптимизировать?
Lua:
function GetPlayerWeaponID(weaponid)
    if weaponid == 0 then
        return "Fist"
    elseif weaponid == 1 then
        return "Brass Knuckles"
    elseif weaponid == 2 then
        return "Golf Club"
    elseif weaponid == 3 then
        return "Nightstick"
    elseif weaponid == 4 then
        return "Knife"
    elseif weaponid == 5 then
        return "Baseball Bat"
    elseif weaponid == 6 then
        return "Shovel"
    elseif weaponid == 7 then
        return "Pool Cue"
    elseif weaponid == 8 then
        return "Katana"
    elseif weaponid == 9 then
        return "Chainsaw"
    elseif weaponid == 10 then
        return "Purple Dildo"
    elseif weaponid == 11 then
        return "Dildo"
    elseif weaponid == 12 then
        return "Vibrator"
    elseif weaponid == 13 then
        return "Silver Vibrator"
    elseif weaponid == 14 then
        return "Flowers"
    elseif weaponid == 15 then
        return "Cane"
    elseif weaponid == 16 then
        return "Grenade"
    elseif weaponid == 17 then
        return "Tear Gas"
    elseif weaponid == 18 then
        return "Molotov Cocktail"
    elseif weaponid == 22 then
        return "9mm"
    elseif weaponid == 23 then
        return "Silenced 9mm"
    elseif weaponid == 24 then
        return "Desert Eagle"
    elseif weaponid == 25 then
        return "Shotgun"
    elseif weaponid == 26 then
        return "Sawnoff Shotgun"
    elseif weaponid == 27 then
        return "Combat Shotgun"
    elseif weaponid == 28 then
        return "Micro SMG/Uzi"
    elseif weaponid == 29 then
        return "MP5"
    elseif weaponid == 30 then
        return "AK-47"
    elseif weaponid == 31 then
        return "M4"
    elseif weaponid == 32 then
        return "Tec-9"
    elseif weaponid == 33 then
        return "Country Rifle"
    elseif weaponid == 34 then
        return "Sniper Rifle"
    elseif weaponid == 35 then
        return "RPG"
    elseif weaponid == 36 then
        return "HS Rocket"
    elseif weaponid == 37 then
        return "Flamethrower"
    elseif weaponid == 38 then
        return "Minigun"
    elseif weaponid == 39 then
        return "Satchel Charge"
    elseif weaponid == 40 then
        return "Detonator"
    elseif weaponid == 41 then
        return "Spraycan"
    elseif weaponid == 42 then
        return "Fire Extinguisher"
    end
end

Lua:
function getweaponname(weapon)
  local names = {
  [0] = "Fist",
  [1] = "Brass Knuckles",
  [2] = "Golf Club",
  [3] = "Nightstick",
  [4] = "Knife",
  [5] = "Baseball Bat",
  [6] = "Shovel",
  [7] = "Pool Cue",
  [8] = "Katana",
  [9] = "Chainsaw",
  [10] = "Purple Dildo",
  [11] = "Dildo",
  [12] = "Vibrator",
  [13] = "Silver Vibrator",
  [14] = "Flowers",
  [15] = "Cane",
  [16] = "Grenade",
  [17] = "Tear Gas",
  [18] = "Molotov Cocktail",
  [22] = "9mm",
  [23] = "Silenced 9mm",
  [24] = "Desert Eagle",
  [25] = "Shotgun",
  [26] = "Sawnoff Shotgun",
  [27] = "Combat Shotgun",
  [28] = "Micro SMG/Uzi",
  [29] = "MP5",
  [30] = "AK-47",
  [31] = "M4",
  [32] = "Tec-9",
  [33] = "Country Rifle",
  [34] = "Sniper Rifle",
  [35] = "RPG",
  [36] = "HS Rocket",
  [37] = "Flamethrower",
  [38] = "Minigun",
  [39] = "Satchel Charge",
  [40] = "Detonator",
  [41] = "Spraycan",
  [42] = "Fire Extinguisher",
  [43] = "Camera",
  [44] = "Night Vis Goggles",
  [45] = "Thermal Goggles",
  [46] = "Parachute" }
  return names[weapon]
end
))
 

ynhhoJ

Известный
102
6
Пытаюсь сделать скрипт который будет показывать растояние до какого-то игрока, сделал так:
Lua:
function GetDistanceBetweenPlayers(p1,p2)
    local resul2, player1 = sampGetCharHandleBySampPlayerId(p1)
    local x, y, z = getCharCoordinates(player1)
    local result2, player2 = sampGetCharHandleBySampPlayerId(p2)
    local x_, y_, z_ = getCharCoordinates(player2)
    return math.sqrt(math.pow(math.abs(x_-x),2)+math.pow(math.abs(y_-y),2)+math.pow(math.abs(z_-z),2))
end

Но когда этот скрипт выполняется, игру крашит, а в логах показывает это:
Код:
[17:26:20.070768] (debug)    Add thread 17A4D115 to SCM-thread queue
[17:26:25.630770] (error)    opcode '00A0' call caused an unhandled exception
[17:26:27.643769] (system)    Unloading...

Делал по примеру скрипта из PAWN:
PHP:
Float:GetDistanceBetweenPlayers(p1,p2)
{
    new Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2;
    if(!IsPlayerConnected(p1) || !IsPlayerConnected(p2)) return -1.00;
    GetPlayerPos(p1,x1,y1,z1);
    GetPlayerPos(p2,x2,y2,z2);
    return floatsqroot(floatpower(floatabs(floatsub(x2,x1)),2)+floatpower(floatabs(floatsub(y2,y1)),2)+floatpower(floatabs(floatsub(z2,z1)),2));
}

Что я сделал не так?
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Пытаюсь сделать скрипт который будет показывать растояние до какого-то игрока, сделал так:
Lua:
function GetDistanceBetweenPlayers(p1,p2)
    local resul2, player1 = sampGetCharHandleBySampPlayerId(p1)
    local x, y, z = getCharCoordinates(player1)
    local result2, player2 = sampGetCharHandleBySampPlayerId(p2)
    local x_, y_, z_ = getCharCoordinates(player2)
    return math.sqrt(math.pow(math.abs(x_-x),2)+math.pow(math.abs(y_-y),2)+math.pow(math.abs(z_-z),2))
end

Но когда этот скрипт выполняется, игру крашит, а в логах показывает это:
Код:
[17:26:20.070768] (debug)    Add thread 17A4D115 to SCM-thread queue
[17:26:25.630770] (error)    opcode '00A0' call caused an unhandled exception
[17:26:27.643769] (system)    Unloading...

Делал по примеру скрипта из PAWN:
PHP:
Float:GetDistanceBetweenPlayers(p1,p2)
{
    new Float:x1,Float:y1,Float:z1,Float:x2,Float:y2,Float:z2;
    if(!IsPlayerConnected(p1) || !IsPlayerConnected(p2)) return -1.00;
    GetPlayerPos(p1,x1,y1,z1);
    GetPlayerPos(p2,x2,y2,z2);
    return floatsqroot(floatpower(floatabs(floatsub(x2,x1)),2)+floatpower(floatabs(floatsub(y2,y1)),2)+floatpower(floatabs(floatsub(z2,z1)),2));
}

Что я сделал не так?

Lua:
function getDistanceBetweenPlayers(id, id2)
    local id = tonumber(id) -- Это на всякий случай
    local id2 = tonumber(id2) -- Это на всякий случай
    local result, handle = sampGetCharHandleBySampPlayerId(id)
    local exists, phandle = sampGetCharHandleBySampPlayerId(id2)
    if result and exists and doesCharExist(handle) and doesCharExist(phandle) then
        local X, Y, Z = getCharCoordinates(handle)
        local pX, pY, pZ = getCharCoordinates(phandle)
        local dist = math.sqrt(math.pow(math.abs(pX-X),2)+math.pow(math.abs(pY-Y),2)+math.pow(math.abs(pZ-Z),2))
        return dist
    end
end

Только функция будет работать, если игроки будут находится в зоне твоего стрима.
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Lua:
function getDistanceBetweenPlayers(id, id2)
    local id = tonumber(id) -- Это на всякий случай
    local id2 = tonumber(id2) -- Это на всякий случай
    local result, handle = sampGetCharHandleBySampPlayerId(id)
    local exists, phandle = sampGetCharHandleBySampPlayerId(id2)
    if result and exists and doesCharExist(handle) and doesCharExist(phandle) then
        local X, Y, Z = getCharCoordinates(handle)
        local pX, pY, pZ = getCharCoordinates(phandle)
        local dist = math.sqrt(math.pow(math.abs(pX-X),2)+math.pow(math.abs(pY-Y),2)+math.pow(math.abs(pZ-Z),2))
        return dist
    end
end

Только функция будет работать, если игроки будут находится в зоне твоего стрима.

Lua:
function getDistanceBetweenPlayers(id, id2)
    local _, myid = sampGetPlayerIdByCharHandle(PLAYER_PED) -- Мой ID
    local id = tonumber(id) -- Это на всякий случай
    local id2 = tonumber(id2) -- Это на всякий случай
    if sampIsPlayerConnected(id) or id == myid then
        if sampIsPlayerConnected(id2) or id2 == myid then
            local result, handle = sampGetCharHandleBySampPlayerId(id)
            local exists, phandle = sampGetCharHandleBySampPlayerId(id2)
            if result and exists and doesCharExist(handle) and doesCharExist(phandle) then
                local X, Y, Z = getCharCoordinates(handle)
                local pX, pY, pZ = getCharCoordinates(phandle)
                local dist = math.sqrt(math.pow(math.abs(pX-X),2)+math.pow(math.abs(pY-Y),2)+math.pow(math.abs(pZ-Z),2))
                return dist
            end
        end
    end
end

Ну вот ещё с проверками на то, что игрок на сервере.
 
  • Нравится
Реакции: ynhhoJ

ynhhoJ

Известный
102
6
Код:
bad argument #2 to 'format' (no value)
@imring ,ругается на:
Lua:
sampAddChatMessage(string.format("%f",getDistanceBetweenPlayers(playerid,killerId)),0xB4B4B4)
Хотя я вроде всё правильно сделал...
 

imring

Ride the Lightning
Всефорумный модератор
2,355
2,516
Код:
bad argument #2 to 'format' (no value)
@imring ,ругается на:
Lua:
sampAddChatMessage(string.format("%f",getDistanceBetweenPlayers(playerid,killerId)),0xB4B4B4)
Хотя я вроде всё правильно сделал...
Если не сработает.
Пробуй так:
Lua:
sampAddChatMessage(getDistanceBetweenPlayers(playerid,killerId),0xB4B4B4)
 

playerid

Новичок
10
0
Кому не в падлу сделайте шаблон string.match по этой строчке
[A] Nick_Name[111]: qq
 

FYP

Известный
Автор темы
Администратор
1,758
5,722
Теперь уже работает, но текста нет :D
потому что какие-то проверки не проходят и значение не возвращается.
для вычисления дистанции уже есть функция: getDistanceBetweenCoords3d(float x1, float y1, float z1, float x2, float y2, float z2)
Lua:
function getDistanceBetweenPlayers(id1, id2)
    local result, ped1 = sampGetCharHandleBySampPlayerId(id1)
    if result then
        local result, ped2 = sampGetCharHandleBySampPlayerId(id2)
        if result then
            local x1, y1, z1 = getCharCoordinates(ped1)
            local x2, y2, z2 = getCharCoordinates(ped2)
            return getDistanceBetweenCoords3d(x1, y1, z1, x2, y2, z2)
        end
    end
    return nil -- вернуть nil, если дистанцию вычислить не удалось
end
Как можно узнать узнать версию/название/авторов другого скрипта?
Видел в этой теме код, но что-то я его не могу найти.
получить хендл нужного скрипта и обращаться к требуемым данным: lua - luascript | BlastHack — DEV_WIKI(https://blast.hk/wiki/lua:luascript)
Как отослать пакет по протоколу https?
либа lua-requests, я постил её в этой теме
Как там можно вместо любого символа (точка) указать конкретный?
просто использовать этот символ в патерне
 
  • Нравится
Реакции: ishi и ynhhoJ

ynhhoJ

Известный
102
6
потому что какие-то проверки не проходят и значение не возвращается.
для вычисления дистанции уже есть функция: getDistanceBetweenCoords3d(float x1, float y1, float z1, float x2, float y2, float z2)
Lua:
function getDistanceBetweenPlayers(id1, id2)
    local result, ped1 = sampGetCharHandleBySampPlayerId(id1)
    if result then
        local result, ped2 = sampGetCharHandleBySampPlayerId(id2)
        if result then
            local x1, y1, z1 = getCharCoordinates(ped1)
            local x2, y2, z2 = getCharCoordinates(ped2)
            return getDistanceBetweenCoords3d(x1, y1, z1, x2, y2, z2)
        end
    end
    return nil -- вернуть nil, если дистанцию вычислить не удалось
end

Дело в том что в 90% смертей не определяется дистанция, значит делать подобное не имеет смысла...