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

sat0ry

Известный
1,084
301
Можно ли как то удалить renderFontDrawText? Ибо у меня просто переодически он налаживается сам на себя при повторном использовании клик варпа
до:
1.jpg

после 5 использований:

2.jpg

сам код:
Lua:
local font = renderCreateFont('Arial', 9, 9)

function click_warp()
    lua_thread.create(function()
        while true do
        if cursorEnabled and not window.v and not teleportmenu.v and not templeader.v then
          local mode = sampGetCursorMode()
          if mode == 0 then
            showCursor(true)
          end
          local sx, sy = getCursorPos()
          local sw, sh = getScreenResolution()
          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()
            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
              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("{FFFFFF}%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 = 0xFFFFFFFF
                    if isKeyDown(VK_RBUTTON) then
                      tpIntoCar = car
                      color = 0xFFFFFFFF
                    end
                    renderFontDrawText(font, "{FFFFFF}Удерживайте ПКМ, чтобы телепортироваться в машину", sx, sy - hoffs * 3, color)
                  end
                end

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

                if isKeyDown(VK_LBUTTON) then
                  if tpIntoCar then
                    if not jumpIntoCar(tpIntoCar) then
                      teleportPlayer(pos.x, pos.y, pos.z)
                      local veh = storeCarCharIsInNoSave(playerPed)
                      local cordsVeh = {getCarCoordinates(veh)}
                      setCarCoordinates(veh, cordsVeh[1], cordsVeh[2], cordsVeh[3])
                    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 - 1.1
                    end
                    teleportPlayer(pos.x, pos.y, pos.z)
                  end
                  removePointMarker()

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

Dmitriy Makarov

25.05.2021
Проверенный
2,512
1,139
Можно ли как то удалить renderFontDrawText? Ибо у меня просто переодически он налаживается сам на себя при повторном использовании клик варпа
до:
Посмотреть вложение 145189
после 5 использований:

Посмотреть вложение 145190
сам код:
Lua:
local font = renderCreateFont('Arial', 9, 9)

function click_warp()
    lua_thread.create(function()
        while true do
        if cursorEnabled and not window.v and not teleportmenu.v and not templeader.v then
          local mode = sampGetCursorMode()
          if mode == 0 then
            showCursor(true)
          end
          local sx, sy = getCursorPos()
          local sw, sh = getScreenResolution()
          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()
            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
              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("{FFFFFF}%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 = 0xFFFFFFFF
                    if isKeyDown(VK_RBUTTON) then
                      tpIntoCar = car
                      color = 0xFFFFFFFF
                    end
                    renderFontDrawText(font, "{FFFFFF}Удерживайте ПКМ, чтобы телепортироваться в машину", sx, sy - hoffs * 3, color)
                  end
                end

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

                if isKeyDown(VK_LBUTTON) then
                  if tpIntoCar then
                    if not jumpIntoCar(tpIntoCar) then
                      teleportPlayer(pos.x, pos.y, pos.z)
                      local veh = storeCarCharIsInNoSave(playerPed)
                      local cordsVeh = {getCarCoordinates(veh)}
                      setCarCoordinates(veh, cordsVeh[1], cordsVeh[2], cordsVeh[3])
                    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 - 1.1
                    end
                    teleportPlayer(pos.x, pos.y, pos.z)
                  end
                  removePointMarker()

                  while isKeyDown(VK_LBUTTON) do wait(0) end
                  showCursor(false)
                end
              end
            end
          end
        end
        wait(0)
        removePointMarker()
        end
    end)
end
Ну так удали строчки с функцией renderFontDrawText и всё.)
 

Z3roKwq

Известный
290
154
при загрузке кфг из файла вылазит: cannot convert 'string' to 'int'

mainini.settings.sizetr = sizetr[0] - строчка из за которой пошла проблема

как я понял нужно что то добавить, а что хз
 

accord-

Потрачен
436
81
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
какое название у toggle button в стиле
 

Dmitriy Makarov

25.05.2021
Проверенный
2,512
1,139
Lua:
if sampTextdrawIsExists(ID_Текстдрава) then
    sampSendClickTextdraw(ID_Текстдрава)
end
ID текстдравов могут повторяться. Где-то краем ушка слышал, что дополнительно проверяют координаты текстдрава, чтобы не кликнуть на левый текстдрав с таким же ID. Но это уже с помощью onShowTextDraw (Или как там событие называется)
 
  • Нравится
Реакции: ShitKatsan

accord-

Потрачен
436
81
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
ImGui::TogleButton это кастомная функа, там используется ImGui::InvisibleButton, так что логично если Button
Нету InvisibleButton, мне именно цвет ползунка поменять
1651038164774.png
, imgui если что
 

Smeruxa

smeruxa.ru
Проверенный
1,432
800
Так я не понимаю, тебе на луа или на с++ надо
Причем тут это?

та ну, так не интерсно)
У тебя поток прошлый не завершается, скорее всего, поэтому рисуется снова, теперь разбирайся
P.s. да, там break нету почему-то, ты ведь перенес это в поток, а потом это как отдельная хуйня, так еще и беск цикл херачнул, оно будет работать всегда, т.е. в конце тебе надо поставить break, сейчас с тулса своего скину как я реализовал
P.s. Тупо объяснил, короче
Когда ты вызываешь функцию, ты создаешь новый поток, в потоке пишешь беск. цикл, а потом когда ты тепаешься - цикл не завершается. Текст у тебя рисуется тогда, когда курсор включен, а ты когда тепаешься - его отключаешь, НО цикл у тебя - не завершается. В следующий раз, когда ты тепнешься куда-то, у тебя уже два потока будет, т.е. будет два текста, т.к. у тебя включен курсор и т.д.
Lua:
    lua_thread.create(function()
        while true do
            if cursorEnabled then
                local mode = sampGetCursorMode()
                if mode == 0 then
                    showCursor(true)
                end
                local sx, sy = getCursorPos()
                local sw, sh = windowCoordinates[1], windowCoordinates[2]
                local color = join_argb(255, elements.colors.colorClickWarpText.r, elements.colors.colorClickWarpText.g, elements.colors.colorClickWarpText.b)
                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()
                    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
                        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(fonts.clickWarp)
                            sy = sy - 2
                            sx = sx - 2
                            renderFontDrawText(fonts.clickWarp, string.format("%0.2fm", dist), sx, sy - hoffs, color)
                            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)))
                                    if isKeyDown(VK_RBUTTON) then
                                        tpIntoCar = car
                                    end
                                    renderFontDrawText(fonts.clickWarp, "Hold right mouse button to teleport into the car", sx, sy - hoffs * 3, color)
                                end
                            end
                            createPointMarker(pos.x, pos.y, pos.z)
                            if isKeyDown(VK_LBUTTON) then
                                if tpIntoCar then
                                    if not jumpIntoCar(tpIntoCar) then
                                        teleportPlayer(pos.x, pos.y, pos.z)
                                        local veh = storeCarCharIsInNoSave(playerPed)
                                        local cordsVeh = {getCarCoordinates(veh)}
                                        setCarCoordinates(veh, cordsVeh[1], cordsVeh[2], cordsVeh[3])
                                        cursorEnabled = false
                                        showCursor(false)
                                        removePointMarker()
                                        break
                                    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 - 1.1
                                    end
                                    teleportPlayer(pos.x, pos.y, pos.z)
                                    cursorEnabled = false
                                    showCursor(false)
                                    removePointMarker()
                                    break
                                end
                                while isKeyDown(VK_LBUTTON) do wait(0) end
                                cursorEnabled = false
                                showCursor(false)
                                removePointMarker()
                                break
                            end
                        end
                    end
                end
            end
            wait(0)
            removePointMarker()
        end
        cursorEnabled = false
        showCursor(false)
        removePointMarker()
    end)
end
 
Последнее редактирование:
  • Нравится
Реакции: sat0ry

shrug228

Активный
212
77
Через asyncHttpResponse получаю данные и перевожу в JSON:
Lua:
asyncHttpRequest('GET', url, nil, function (response)
    sampAddChatMessage(decodeJson(response.text)['current']['weather']['main'], -1) -- attempt to index field 'current'
end)
Как из них получить current.weather.main (для наглядности ниже обрезанная структура ответа):
JSON:
{
  "lat": 33.44,
  "lon": -94.04,
  "timezone": "America/Chicago",
  "timezone_offset": -21600,
  "current": {
    "dt": 1618317040,
    "sunrise": 1618282134,
    "sunset": 1618333901,
    "temp": 284.07,
    "feels_like": 282.84,
    "pressure": 1019,
    "humidity": 62,
    "dew_point": 277.08,
    "uvi": 0.89,
    "clouds": 0,
    "visibility": 10000,
    "wind_speed": 6,
    "wind_deg": 300,
    "weather": [
      {
        "id": 500,
        "main": "Rain",
        "description": "light rain",
        "icon": "10d"
      }
    ],
    "rain": {
      "1h": 0.21
    }
  }
]

Через asyncHttpResponse получаю данные и перевожу в JSON:
Lua:
asyncHttpRequest('GET', url, nil, function (response)
    sampAddChatMessage(decodeJson(response.text)['current']['weather']['main'], -1) -- attempt to index field 'current'
end)
Как из них получить current.weather.main (для наглядности ниже обрезанная структура ответа):
JSON:
{
  "lat": 33.44,
  "lon": -94.04,
  "timezone": "America/Chicago",
  "timezone_offset": -21600,
  "current": {
    "dt": 1618317040,
    "sunrise": 1618282134,
    "sunset": 1618333901,
    "temp": 284.07,
    "feels_like": 282.84,
    "pressure": 1019,
    "humidity": 62,
    "dew_point": 277.08,
    "uvi": 0.89,
    "clouds": 0,
    "visibility": 10000,
    "wind_speed": 6,
    "wind_deg": 300,
    "weather": [
      {
        "id": 500,
        "main": "Rain",
        "description": "light rain",
        "icon": "10d"
      }
    ],
    "rain": {
      "1h": 0.21
    }
  }
]
Я долбоеб, делал неправильно запрос, соответственно и на выходе данные не совсем те, что мне нужно.
 
Последнее редактирование: