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

Rei

Известный
Друг
1,611
1,668
Lua:
[/B]
function draw()
while true do wait(0)
        car = storeCarCharIsInNoSave(PLAYER_PED)
        if isCharInCar(PLAYER_PED,car) then
            if not loadTextureDictionary("name") then return end
                useRenderCommands(true)
                int = loadSprite("texturename")
                while true do
                wait(0)
                drawSprite(int, 500, 400, 16.0, 64.0, 255, 255, 255, 255)
            end
        end
    end
end
[B]
Есть такой код, всё работает как и нужно кроме того, что когда выхожу из машины - загруженная картинка остаётся. Как можно исправить данную проблемку?
не плодить бесконечные циклы в бесконечном цикле
 
  • Нравится
Реакции: The End

chockscrot

Участник
42
1
how can I somehow use the if isKeyJustPressed (VK_P) in this code?


sampRegisterChatCommand:
require "lib.moonloader"
local samp = require 'lib.samp.events'
local activate = true

function main()
    while not isSampAvailable() do wait(0) end
    if not sampIsLocalPlayerSpawned() then return false end
    sampRegisterChatCommand('pzda', function()
    activate = not activate
    if activate then
        setCharProofs(playerPed, true, true, true, true, true)
        writeMemory(0x96916E, 1, 1, false)
    else
        setCharProofs(playerPed, false, false, false, false, false)
        writeMemory(0x96916E, 1, 0, false)
    end
    printStringNow('~g~ '.. (activate and 'ACTIVATED' or 'DEACTIVATED'), 1000)
    end)
    while true do wait(0)
        if activate then
            setCharProofs(playerPed, true, true, true, true, true)
            writeMemory(0x96916E, 1, 1, false)
        end
        if testCheat('ggm') then
            activate = not activate
            if activate then
                setCharProofs(playerPed, true, true, true, true, true)
                writeMemory(0x96916E, 1, 1, false)
            else
                setCharProofs(playerPed, false, false, false, false, false)
                writeMemory(0x96916E, 1, 0, false)
            end
            printStringNow('~g~ '.. (activate and 'ACTIVATED' or 'DEACTIVATED'), 1000)
        end
    end
end
 

Hatiko

Известный
Проверенный
1,494
617
how can I somehow use the if isKeyJustPressed (VK_P) in this code?
Lua:
function main()
    while not isSampAvailable() do wait(0) end
    if not sampIsLocalPlayerSpawned() then return false end
    sampRegisterChatCommand('pzda', function() -- pzda - abbreviated Russian bad word :D
    activate = not activate
    if activate then
        setCharProofs(playerPed, true, true, true, true, true)
        writeMemory(0x96916E, 1, 1, false)
    else
        setCharProofs(playerPed, false, false, false, false, false)
        writeMemory(0x96916E, 1, 0, false)
    end
    printStringNow('~g~ '.. (activate and 'ACTIVATED' or 'DEACTIVATED'), 1000)
    end)
    while true do wait(0)
        -- if activate then -- This is unnecessary
        --     setCharProofs(playerPed, true, true, true, true, true)
        --     writeMemory(0x96916E, 1, 1, false)
        -- end
        if not sampIsChatInputActive() and isKeyJustPressed(VK_P) then
            activate = not activate
            if activate then
                setCharProofs(playerPed, true, true, true, true, true)
                writeMemory(0x96916E, 1, 1, false)
            else
                setCharProofs(playerPed, false, false, false, false, false)
                writeMemory(0x96916E, 1, 0, false)
            end
            printStringNow('~g~ '.. (activate and 'ACTIVATED' or 'DEACTIVATED'), 1000)
        end
    end
end
 

Kirill Dumchik

Участник
61
3
Видел где-то скрипт, что пишешь команду /spawnme и игрока спавнит (где-то на ферме).
Как можно такое сделать? Не могу понять как заспавнить самого себя
 

moreveal

Известный
Проверенный
919
617
Суть скрипта думаю понятна. Есть баг, когда пишу /pogod и айди игрока, которого нету на сервере (которых), то меня крашит. Как сделать проверку есть-ли игрок на сервере?
Или в целом как пофиксить краш





Lua:




function cmd_pogod(pam)
lua_thread.create(function()
local id, nick = pam:match("(%d+)%s+(.+)")
nick = sampGetPlayerNickname(nick)
if id and nick then
sampSendChat('/sms '..id..' Проверяю дело - '..nick..'.')
wait(500)
sampSendChat('/wanted '..sampGetPlayerIdByNickname(nick))
wait(200)
main_window_state.v = false
wait(5)
sampProcessChatInput('/go ' .. id .. '')
wait(3)
imgui.ShowCursor = false
else
sampAddChatMessage('TEXT будет', -1)
end
end)
end
sampIsPlayerConnected(id)
 

Hatiko

Известный
Проверенный
1,494
617
Суть скрипта думаю понятна. Есть баг, когда пишу /pogod и айди игрока, которого нету на сервере (которых), то меня крашит. Как сделать проверку есть-ли игрок на сервере?
Или в целом как пофиксить краш
В следующий раз вставляй код с синтаксисом и табуляции, либо не будут вообще отвечать, т.к. сложно ориентироваться
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
 
  • Нравится
  • Влюблен
Реакции: Сheesecake и chapo

Artem90

Новичок
11
0
Не работает бинд клавиш в lua скриптах.
в загруженных скриптах либо свойх не работает:
для примера пытался свойм скриптом

код:
local vkeys = require 'vkeys'
require "lib.moonloader"

function main()
    while true do
        wait(0)
        if isKeyJustPressed(VK_F2) then
            print('Pressed ctrl+w')
            -- body
        end
    end

    
end

Ноутбук dell 5490
os :windows 10
загружены все стандартные библиотеки.
 
У

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

Гость
Хотел изменить задержку - не получилось,всё та же задержка...В чём проблема?Помогите пожалуйста.
Lua:
require "moonloader"
local eblya = require("events")
local pisuneckiy = 0


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

    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

function eblya.onSetPlayerTime()
    print("onSetPlayerTime")
    if sampIsDialogActive() and sampGetDialogCaption():find("Проверка на робота") then
        print("Proverka na robota")
        knopka()
    end
end

function eblya.onSetWeather()
    print("onSetWeather")
    if sampIsDialogActive() and sampGetDialogCaption():find("Проверка на робота") then
        print("Proverka na robota")
        knopka()
    end
end

function knopka()
    lua_thread.create(function()
        print("Najali knopku")
        setCharKeyDown(VK_RETURN, true)
        wait(0)
        setCharKeyDown(VK_RETURN, false)
    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,494
617
Не работает бинд клавиш в 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 если его включить/отключить. Буду очень благодарен)
Это в раздел услуги переделки скриптов. Просишь большой скрипт переделать, это не к вопросам.
 
Последнее редактирование: