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

Eugene Crabs

Активный
544
30
Ребят, смотрите. Задан треугольник координатами "X1, Y1"; "X2, Y2"; "X3, Y3". Задача: Найти программно все углы данного треугольника. Как это можно сделать?
 

eEe1125

Участник
70
2
Помогите пожалуйста чтобы скрипт не был активироват при входе (как это щас), а чтобы он активировался по команде /tp. Также чтобы писало ON и OFF если его включить/отключить. Буду очень благодарен)
Lua:
script_name("Click Warp")
script_authors("FYP", "we_sux team")
script_version_number(3)
script_dependencies("SAMPFUNCS")
script_description("Click click, teleport!")
script_moonloader(19)

require"lib.moonloader"
require"lib.sampfuncs"
local Matrix3X3 = require "matrix3x3"
local Vector3D = require "vector3d"


--- Config
keyToggle = VK_MBUTTON
keyApply = VK_LBUTTON


--- Main
function main()
  if not isSampfuncsLoaded() then return end
  initializeRender()
  while true do

    while isPauseMenuActive() do
      if cursorEnabled then
        showCursor(false)
      end
      wait(100)
    end

    if isKeyDown(keyToggle) then
      cursorEnabled = not cursorEnabled
      showCursor(cursorEnabled)
      while isKeyDown(keyToggle) do wait(80) end
    end

    if cursorEnabled then
      local mode = sampGetCursorMode()
      if mode == 0 then
        showCursor(true)
      end
      local sx, sy = getCursorPos()
      local sw, sh = getScreenResolution()
      -- is cursor in game window bounds?
      if sx >= 0 and sy >= 0 and sx < sw and sy < sh then
        local posX, posY, posZ = convertScreenCoordsToWorld3D(sx, sy, 700.0)
        local camX, camY, camZ = getActiveCameraCoordinates()
        -- search for the collision point
        local result, colpoint = processLineOfSight(camX, camY, camZ, posX, posY, posZ, true, true, false, true, false, false, false)
        if result and colpoint.entity ~= 0 then
          local normal = colpoint.normal
          local pos = Vector3D(colpoint.pos[1], colpoint.pos[2], colpoint.pos[3]) - (Vector3D(normal[1], normal[2], normal[3]) * 0.1)
          local zOffset = 300
          if normal[3] >= 0.5 then zOffset = 1 end
          -- search for the ground position vertically down
          local result, colpoint2 = processLineOfSight(pos.x, pos.y, pos.z + zOffset, pos.x, pos.y, pos.z - 0.3,
            true, true, false, true, false, false, false)
          if result then
            pos = Vector3D(colpoint2.pos[1], colpoint2.pos[2], colpoint2.pos[3] + 1)

            local curX, curY, curZ  = getCharCoordinates(playerPed)
            local dist              = getDistanceBetweenCoords3d(curX, curY, curZ, pos.x, pos.y, pos.z)
            local hoffs             = renderGetFontDrawHeight(font)

            sy = sy - 2
            sx = sx - 2
            renderFontDrawText(font, string.format("%0.2fm", dist), sx, sy - hoffs, 0xEEEEEEEE)

            local tpIntoCar = nil
            if colpoint.entityType == 2 then
              local car = getVehiclePointerHandle(colpoint.entity)
              if doesVehicleExist(car) and (not isCharInAnyCar(playerPed) or storeCarCharIsInNoSave(playerPed) ~= car) then
                displayVehicleName(sx, sy - hoffs * 2, getNameOfVehicleModel(getCarModel(car)))
                local color = 0xAAFFFFFF
                if isKeyDown(VK_RBUTTON) then
                  tpIntoCar = car
                  color = 0xFFFFFFFF
                end
                renderFontDrawText(font2, "Hold right mouse button to teleport into the car", sx, sy - hoffs * 3, color)
              end
            end

            createPointMarker(pos.x, pos.y, pos.z)

            -- teleport!
            if isKeyDown(keyApply) then
              if tpIntoCar then
                if not jumpIntoCar(tpIntoCar) then
                  -- teleport to the car if there is no free seats
                  teleportPlayer(pos.x, pos.y, pos.z)
                end
              else
                if isCharInAnyCar(playerPed) then
                  local norm = Vector3D(colpoint.normal[1], colpoint.normal[2], 0)
                  local norm2 = Vector3D(colpoint2.normal[1], colpoint2.normal[2], colpoint2.normal[3])
                  rotateCarAroundUpAxis(storeCarCharIsInNoSave(playerPed), norm2)
                  pos = pos - norm * 1.8
                  pos.z = pos.z - 0.8
                end
                teleportPlayer(pos.x, pos.y, pos.z)
              end
              removePointMarker()

              while isKeyDown(keyApply) do wait(0) end
              showCursor(false)
            end
          end
        end
      end
    end
    wait(0)
    removePointMarker()
  end
end

function initializeRender()
  font = renderCreateFont("Tahoma", 10, FCR_BOLD + FCR_BORDER)
  font2 = renderCreateFont("Arial", 8, FCR_ITALICS + FCR_BORDER)
end


--- Functions
function rotateCarAroundUpAxis(car, vec)
  local mat = Matrix3X3(getVehicleRotationMatrix(car))
  local rotAxis = Vector3D(mat.up:get())
  vec:normalize()
  rotAxis:normalize()
  local theta = math.acos(rotAxis:dotProduct(vec))
  if theta ~= 0 then
    rotAxis:crossProduct(vec)
    rotAxis:normalize()
    rotAxis:zeroNearZero()
    mat = mat:rotate(rotAxis, -theta)
  end
  setVehicleRotationMatrix(car, mat:get())
end

function readFloatArray(ptr, idx)
  return representIntAsFloat(readMemory(ptr + idx * 4, 4, false))
end

function writeFloatArray(ptr, idx, value)
  writeMemory(ptr + idx * 4, 4, representFloatAsInt(value), false)
end

function getVehicleRotationMatrix(car)
  local entityPtr = getCarPointer(car)
  if entityPtr ~= 0 then
    local mat = readMemory(entityPtr + 0x14, 4, false)
    if mat ~= 0 then
      local rx, ry, rz, fx, fy, fz, ux, uy, uz
      rx = readFloatArray(mat, 0)
      ry = readFloatArray(mat, 1)
      rz = readFloatArray(mat, 2)

      fx = readFloatArray(mat, 4)
      fy = readFloatArray(mat, 5)
      fz = readFloatArray(mat, 6)

      ux = readFloatArray(mat, 8)
      uy = readFloatArray(mat, 9)
      uz = readFloatArray(mat, 10)
      return rx, ry, rz, fx, fy, fz, ux, uy, uz
    end
  end
end

function setVehicleRotationMatrix(car, rx, ry, rz, fx, fy, fz, ux, uy, uz)
  local entityPtr = getCarPointer(car)
  if entityPtr ~= 0 then
    local mat = readMemory(entityPtr + 0x14, 4, false)
    if mat ~= 0 then
      writeFloatArray(mat, 0, rx)
      writeFloatArray(mat, 1, ry)
      writeFloatArray(mat, 2, rz)

      writeFloatArray(mat, 4, fx)
      writeFloatArray(mat, 5, fy)
      writeFloatArray(mat, 6, fz)

      writeFloatArray(mat, 8, ux)
      writeFloatArray(mat, 9, uy)
      writeFloatArray(mat, 10, uz)
    end
  end
end

function displayVehicleName(x, y, gxt)
  x, y = convertWindowScreenCoordsToGameScreenCoords(x, y)
  useRenderCommands(true)
  setTextWrapx(640.0)
  setTextProportional(true)
  setTextJustify(false)
  setTextScale(0.33, 0.8)
  setTextDropshadow(0, 0, 0, 0, 0)
  setTextColour(255, 255, 255, 230)
  setTextEdge(1, 0, 0, 0, 100)
  setTextFont(1)
  displayText(x, y, gxt)
end

function createPointMarker(x, y, z)
  pointMarker = createUser3dMarker(x, y, z + 0.3, 4)
end

function removePointMarker()
  if pointMarker then
    removeUser3dMarker(pointMarker)
    pointMarker = nil
  end
end

function getCarFreeSeat(car)
  if doesCharExist(getDriverOfCar(car)) then
    local maxPassengers = getMaximumNumberOfPassengers(car)
    for i = 0, maxPassengers do
      if isCarPassengerSeatFree(car, i) then
        return i + 1
      end
    end
    return nil -- no free seats
  else
    return 0 -- driver seat
  end
end

function jumpIntoCar(car)
  local seat = getCarFreeSeat(car)
  if not seat then return false end                         -- no free seats
  if seat == 0 then warpCharIntoCar(playerPed, car)         -- driver seat
  else warpCharIntoCarAsPassenger(playerPed, car, seat - 1) -- passenger seat
  end
  restoreCameraJumpcut()
  return true
end

function teleportPlayer(x, y, z)
  if isCharInAnyCar(playerPed) then
    setCharCoordinates(playerPed, x, y, z)
  end
  setCharCoordinatesDontResetAnim(playerPed, x, y, z)
end

function setCharCoordinatesDontResetAnim(char, x, y, z)
  if doesCharExist(char) then
    local ptr = getCharPointer(char)
    setEntityCoordinates(ptr, x, y, z)
  end
end

function setEntityCoordinates(entityPtr, x, y, z)
  if entityPtr ~= 0 then
    local matrixPtr = readMemory(entityPtr + 0x14, 4, false)
    if matrixPtr ~= 0 then
      local posPtr = matrixPtr + 0x30
      writeMemory(posPtr + 0, 4, representFloatAsInt(x), false) -- X
      writeMemory(posPtr + 4, 4, representFloatAsInt(y), false) -- Y
      writeMemory(posPtr + 8, 4, representFloatAsInt(z), false) -- Z
    end
  end
end

function showCursor(toggle)
  if toggle then
    sampSetCursorMode(CMODE_LOCKCAM)
  else
    sampToggleCursor(false)
  end
  cursorEnabled = toggle
end
 

Hatiko

Известный
Проверенный
1,470
612
Не работает бинд клавиш в lua скриптах.
в загруженных скриптах либо свойх не работает:

Не забывай ставить проверку на загрузку сампа. Ибо скриты будут крашиться при старте игры.

Lua:
local vkeys = require 'vkeys'
require "lib.moonloader"

function main()
    repeat wait(100) until isSampAvailable() -- Проверка на загрузку сампа
    while true do
        wait(0)
        if isKeyJustPressed(VK_F2) then
            print('Pressed ctrl+w')
            -- body
        end
    end
end


Хотел изменить задержку - не получилось,всё та же задержка...В чём проблема?Помогите пожалуйста.

В отдельный поток вынести, ибо у тебя скрипт за 15 сек замораживался.
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do wait(0)
        --
    end

end

lua_thread.create(function()
    while true do
        wait(15000)
        pisuneckiy1, pisuneckiy2 = getTimeOfDay()
        if pisuneckiy1 ~= pisuneckiy then
            pisuneckiy = pisuneckiy1
            print("pisuneckiy")
            if sampIsDialogActive() and sampGetDialogCaption():find("Проверка на робота") then
                print("Proverka na robota")
                knopka()
            end
        end
    end
end)
Ребят, смотрите. Задан треугольник координатами "X1, Y1"; "X2, Y2"; "X3, Y3". Задача: Найти программно все углы данного треугольника. Как это можно сделать?
Векторная тригонометрия. (no ad) https://zaochnik.com/spravochnik/ma...denie-ugla-mezhdu-vektorami-primery-i-reshen/


Помогите пожалуйста чтобы скрипт не был активироват при входе (как это щас), а чтобы он активировался по команде /tp. Также чтобы писало ON и OFF если его включить/отключить. Буду очень благодарен)
Это в раздел услуги переделки скриптов. Просишь большой скрипт переделать, это не к вопросам.
 
Последнее редактирование:

Eugene Crabs

Активный
544
30
Помогите пожалуйста чтобы скрипт не был активироват при входе (как это щас), а чтобы он активировался по команде /tp. Также чтобы писало ON и OFF если его включить/отключить. Буду очень благодарен)
Код абсолютно не читаем, так что я не особо знаю чем помочь. Попробуй закинуть весь мэйн в функцию. В мэйне зарегистрируй команду, которая будет запускать поток с этой самой функцией. Ну и обычный переключатель "not bool" с проверкой на существование потока и его началом и завершением
 

Artem90

Новичок
11
0
Не забывай ставить проверку на загрузку сампа. Ибо скриты будут крашиться при старте игры.
Но проблема в другом не работает биндинг клавиш даже стандартная библиотека reload_all не реагирует на CTRL+R
Moonloader работает скрипты загружаются в консоле все без ошибок
 

Aniki

🐰
Администратор
1,225
1,506
Ребят, смотрите. Задан треугольник координатами "X1, Y1"; "X2, Y2"; "X3, Y3". Задача: Найти программно все углы данного треугольника. Как это можно сделать?
Если конкретно в мунлоадере, то можно так
Lua:
local x1, y1, x2, y2, x3, y3
local a1 = getAngleBetween2dVectors(x1 - x2, y1 - y2, x1 - x3, y1 - y3)
local a2 = getAngleBetween2dVectors(x2 - x1, y2 - y1, x2 - x3, y2 - y3)
local a3 = getAngleBetween2dVectors(x3 - x1, y3 - y1, x3 - x2, y3 - y2)
 

RomanBZK

Активный
138
46
функция в которой ошибка:
function go_to_point(point)

    local dist

    repeat

        set_camera_direction(point)

        wait(0)

        setGameKeyState(1, -255)

        local mx, my, mz = getCharCoordinates(playerPed)

        setGameKeyState(16, 255)

        dist = getDistanceBetweenCoords2d(point.x, point.y, mx, my)

    until dist < 0.6

end


function set_camera_direction(point)

    local c_pos_x, c_pos_y, c_pos_z = getActiveCameraCoordinates()

    local vect = {x = point.x - c_pos_x, y = point.y - c_pos_y}

    local ax = math.atan2(vect.y, -vect.x)

    setCameraPositionUnfixed(0.0, -ax)

end


Скрипт крашается и указывает на wait(0),а если удалить wait(0). То скрипт зависает!
 
У

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

Гость
Не забывай ставить проверку на загрузку сампа. Ибо скриты будут крашиться при старте игры.

Lua:
local vkeys = require 'vkeys'
require "lib.moonloader"

function main()
    repeat wait(100) until isSampAvailable() -- Проверка на загрузку сампа
    while true do
        wait(0)
        if isKeyJustPressed(VK_F2) then
            print('Pressed ctrl+w')
            -- body
        end
    end
end




В отдельный поток вынести, ибо у тебя скрипт за 15 сек замораживался.
Lua:
function main()
    if not isSampLoaded() or not isSampfuncsLoaded() then return end
    while not isSampAvailable() do wait(100) end
    while true do wait(0)
        --
    end

end

lua_thread.create(function()
    while true do
        wait(15000)
        pisuneckiy1, pisuneckiy2 = getTimeOfDay()
        if pisuneckiy1 ~= pisuneckiy then
            pisuneckiy = pisuneckiy1
            print("pisuneckiy")
            if sampIsDialogActive() and sampGetDialogCaption():find("Проверка на робота") then
                print("Proverka na robota")
                knopka()
            end
        end
    end
end)

Векторная тригонометрия. (no ad) https://zaochnik.com/spravochnik/ma...denie-ugla-mezhdu-vektorami-primery-i-reshen/



Это в раздел услуги переделки скриптов. Просишь большой скрипт переделать, это не к вопросам.
не работает
 

Next..

Известный
343
135
функция в которой ошибка:
function go_to_point(point)

    local dist

    repeat

        set_camera_direction(point)

        wait(0)

        setGameKeyState(1, -255)

        local mx, my, mz = getCharCoordinates(playerPed)

        setGameKeyState(16, 255)

        dist = getDistanceBetweenCoords2d(point.x, point.y, mx, my)

    until dist < 0.6

end


function set_camera_direction(point)

    local c_pos_x, c_pos_y, c_pos_z = getActiveCameraCoordinates()

    local vect = {x = point.x - c_pos_x, y = point.y - c_pos_y}

    local ax = math.atan2(vect.y, -vect.x)

    setCameraPositionUnfixed(0.0, -ax)

end


Скрипт крашается и указывает на wait(0),а если удалить wait(0). То скрипт зависает!
задержка вне мейна используется в потоке
 
  • Нравится
Реакции: RomanBZK

Tol4ek

Активный
217
56
Как не отображать в чате определённые сообщения от сервера, но чтобы луа скрипты другие видели и реагировали на эти сообщения?(Мне не надо их менять, просто чтобы они не отображались в чате).
киньте плез плюсик, шоб этих модеров не ждать больше)))))
 

Сheesecake

Участник
60
2
В следующий раз вставляй код с синтаксисом и табуляции, либо не будут вообще отвечать, т.к. сложно ориентироваться
Lua:
function cmd_pogod(pam)
    lua_thread.create(function()
        local id = pam:match("(%d+)")
        if sampIsPlayerConnected(id) then
            local nick = sampGetPlayerNickname(id)
                sampSendChat('/sms '..id..' Проверяю дело - '..nick..'.')
                wait(500)
                sampSendChat('/wanted '..id)
                wait(200)
                main_window_state.v = false
                wait(5)
                sampProcessChatInput('/go ' .. id .. '')
                wait(3)
                imgui.ShowCursor = false          
        else
            sampAddChatMessage('игрока нет на сервере', -1)
        end
    end)
end
С синтаксисом косяк вышел, забыл вставить.
----
Все равно крашится :/
 

Artem90

Новичок
11
0
Уточни информацию, как должно работать
Не работает биндинг клавиш свойх и загруженных скриптов. стандартные библиотеки установлены даже не работает хот кей скрипта reload_all (ctrl+r)
os: windows 10 (включена совместимость Windows 98/Windows ME)
ноутбук : Dell latitude 5490
Сам moonloader работает в консоле все скрипты загружаются без ошибок. но горячие клавиши не реагирует