Полезные сниппеты и функции

Тема в разделе "Lua", создана пользователем SR_team, 14 авг 2016.

  1. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26.10.2013
    Сообщения:
    2.668
    Симпатии:
    1.660
    Репутация:
    438
    [b]Описание:[/b] *текст*
    [code=lua]*код*[/code]
    [b]Пример использования:[/b]
    [code=lua]*код примера*[/code]
     
    #1 SR_team, 14 авг 2016
    Последнее редактирование модератором: 1 окт 2016
    4el0ve4ik, FYP, DarkP1xel и 2 другим нравится это.
  2. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26.10.2013
    Сообщения:
    2.668
    Симпатии:
    1.660
    Репутация:
    438
    Описание: Ищет маркер на карте.
    Использование: local result, x, y, z = SearchMarker(posX, posY, posZ, radius, isRace)
    Код:
    function SearchMarker(posX, posY, posZ, radius, isRace)
        local ret_posX = 0.0
        local ret_posY = 0.0
        local ret_posZ = 0.0
        local isFind = false
    
        for id = 0, 31 do
            local MarkerStruct = 0
            if isRace then MarkerStruct = 0xC7F168 + id * 56
            else MarkerStruct = 0xC7DD88 + id * 160 end
            local MarkerPosX = representIntAsFloat(readMemory(MarkerStruct + 0, 4, false))
            local MarkerPosY = representIntAsFloat(readMemory(MarkerStruct + 4, 4, false))
            local MarkerPosZ = representIntAsFloat(readMemory(MarkerStruct + 8, 4, false))
    
            if MarkerPosX ~= 0.0 or MarkerPosY ~= 0.0 or MarkerPosZ ~= 0.0 then
                if getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ) < radius then
                    ret_posX = MarkerPosX
                    ret_posY = MarkerPosY
                    ret_posZ = MarkerPosZ
                    isFind = true
                    radius = getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ)
                end
            end
        end
    
        return isFind, ret_posX, ret_posY, ret_posZ
    end
    Пример:
    
    script_dependencies("CLEO", "SAMP", "SAMPFUNCS")
    
    ---------------------------------------------------------------------------
    
    require "lib.moonloader"
    require "lib.sampfuncs"
    
    ---------------------------------------------------------------------------
    
    function main()
        if not isSampfuncsLoaded() or not isSampLoaded() then return end
        sampRegisterChatCommand("mycmd", cmd)
    
        while true do wait(0) end
    end
    
    function cmd(param)
        if isPlayerPlaying(playerHandle) then
            local posX, posY, posZ = getCharCoordinates(playerPed)
            local res, x, y, z = SearchMarker(posX, posY, posZ, 50.0, false)
            if res then
                sampAddChatMessage(string.format("Найден обычный маркер в координатах %.2f %.2f %.2f", x, y, z), -1)
            else
                res, x, y, z = SearchMarker(posX, posY, posZ, 50.0, true)
                if res then
                    sampAddChatMessage(string.format("Найден гоночный маркер в координатах %.2f %.2f %.2f", x, y, z), -1)
                else
                    sampAddChatMessage("Маркер не найден", -1)
                end
            end
        end
    end
    
    function SearchMarker(posX, posY, posZ, radius, isRace)
        local ret_posX = 0.0
        local ret_posY = 0.0
        local ret_posZ = 0.0
        local isFind = false
    
        for id = 0, 31 do
            local MarkerStruct = 0
            if isRace then MarkerStruct = 0xC7F168 + id * 56
            else MarkerStruct = 0xC7DD88 + id * 160 end
            local MarkerPosX = representIntAsFloat(readMemory(MarkerStruct + 0, 4, false))
            local MarkerPosY = representIntAsFloat(readMemory(MarkerStruct + 4, 4, false))
            local MarkerPosZ = representIntAsFloat(readMemory(MarkerStruct + 8, 4, false))
    
            if MarkerPosX ~= 0.0 or MarkerPosY ~= 0.0 or MarkerPosZ ~= 0.0 then
                if getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ) < radius then
                    ret_posX = MarkerPosX
                    ret_posY = MarkerPosY
                    ret_posZ = MarkerPosZ
                    isFind = true
                    radius = getDistanceBetweenCoords3d(MarkerPosX, MarkerPosY, MarkerPosZ, posX, posY, posZ)
                end
            end
        end
    
        return isFind, ret_posX, ret_posY, ret_posZ
    end
     
    #2 SR_team, 14 авг 2016
    Последнее редактирование: 14 авг 2016
    romacaddy, RollUp, 4el0ve4ik и 2 другим нравится это.
  3. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26.10.2013
    Сообщения:
    2.668
    Симпатии:
    1.660
    Репутация:
    438
    Описание: Ищет 3D текст на карте.
    Использование: local result, text, color, x, y, z, distance, ignoreWalls, player, vehicle = Search3Dtext(posX, posY, posZ, radius, patern)
    --patern - часть строки или регулярное выражение
    Код:
    
    function Search3Dtext(x, y, z, radius, patern)
        local text = ""
        local color = 0
        local posX = 0.0
        local posY = 0.0
        local posZ = 0.0
        local distance = 0.0
        local ignoreWalls = false
        local player = -1
        local vehicle = -1
        local result = false
    
        for id = 0, 2048 do
            if sampIs3dTextDefined(id) then
                local text2, color2, posX2, posY2, posZ2, distance2, ignoreWalls2, player2, vehicle2 = sampGet3dTextInfoById(id)
                if getDistanceBetweenCoords3d(x, y, z, posX2, posY2, posZ2) < radius then
                    if string.len(patern) ~= 0 then
                        if string.match(text2, patern, 0) ~= nil then result = true end
                    else
                        result = true
                    end
                    if result then
                        text = text2
                        color = color2
                        posX = posX2
                        posY = posY2
                        posZ = posZ2
                        distance = distance2
                        ignoreWalls = ignoreWalls2
                        player = player2
                        vehicle = vehicle2
                        radius = getDistanceBetweenCoords3d(x, y, z, posX, posY, posZ)
                    end
                end
            end
        end
    
        return result, text, color, posX, posY, posZ, distance, ignoreWalls, player, vehicle
    end
    Пример:
    
    script_dependencies("CLEO", "SAMP", "SAMPFUNCS")
    
    ---------------------------------------------------------------------------
    
    require "lib.moonloader"
    require "lib.sampfuncs"
    
    ---------------------------------------------------------------------------
    
    function main()
        if not isSampfuncsLoaded() or not isSampLoaded() then return end
        sampRegisterChatCommand("mycmd", cmd)
    
        while true do wait(0) end
    end
    
    function cmd(param)
        if isPlayerPlaying(playerHandle) then
            local posX, posY, posZ = getCharCoordinates(playerPed)
            local res, text, color, x, y, z, distance, ignoreWalls, player, vehicle = Search3Dtext(posX, posY, posZ, 50.0, "")
            if res then
                sampAddChatMessage(string.format("Найден 3D текст \"%s\" в координатах %.2f %.2f %.2f, дистанция %.2f, id игрока %d, id транспорта %d", text, x, y, z, distance, player, vehicle), color)
            end
        end
    end
    
    function Search3Dtext(x, y, z, radius, patern)
        local text = ""
        local color = 0
        local posX = 0.0
        local posY = 0.0
        local posZ = 0.0
        local distance = 0.0
        local ignoreWalls = false
        local player = -1
        local vehicle = -1
        local result = false
    
        for id = 0, 2048 do
            if sampIs3dTextDefined(id) then
                local text2, color2, posX2, posY2, posZ2, distance2, ignoreWalls2, player2, vehicle2 = sampGet3dTextInfoById(id)
                if getDistanceBetweenCoords3d(x, y, z, posX2, posY2, posZ2) < radius then
                    if string.len(patern) ~= 0 then
                        if string.match(text2, patern, 0) ~= nil then result = true end
                    else
                        result = true
                    end
                    if result then
                        text = text2
                        color = color2
                        posX = posX2
                        posY = posY2
                        posZ = posZ2
                        distance = distance2
                        ignoreWalls = ignoreWalls2
                        player = player2
                        vehicle = vehicle2
                        radius = getDistanceBetweenCoords3d(x, y, z, posX, posY, posZ)
                    end
                end
            end
        end
    
        return result, text, color, posX, posY, posZ, distance, ignoreWalls, player, vehicle
    end
     
    Последние данные очков репутации:
    AppleThe: 2 Очки 9 фев 2017
    #3 SR_team, 14 авг 2016
    Последнее редактирование: 14 авг 2016
    AppleThe, 4el0ve4ik и mac нравится это.
  4. ZeroXruS

    ZeroXruS Пользователь

    Регистрация:
    17.07.2016
    Сообщения:
    17
    Симпатии:
    9
    Репутация:
    0
    Описание: рисует кнопку на экране
    Использование:
    bool
    isClicked= renderDrawButton([Font], Title, posX, posY, sizeX, sizeY, targetX, targetY, boxColor, targetBoxColor, textColor, targetTextColor)
    или
    bool isClicked= renderDrawButtonA([Font], Title, posX, posY, targetX, targetY, boxColor, targetBoxColor, textColor, targetTextColor)
    Код:

    function renderDrawButtonA(d3dFont, Title, posX, posY, targetX, targetY, boxColor, targetBoxColor, textColor, targetTextColor) return renderDrawButton(d3dFont, Title, posX, posY, renderGetFontDrawTextLength(d3dFont, Title), renderGetFontDrawHeight(d3dFont), targetX, targetY, boxColor, targetBoxColor, textColor, targetTextColor) end
    function renderDrawButton(d3dFont, Title, posX, posY, sizeX, sizeY, targetX, targetY, boxColor, targetBoxColor, textColor, targetTextColor)
        local bool= false
        local currentBoxColor= boxColor
        local currentTextColor= textColor
    
        if targetX > posX and targetX < posX + sizeX and targetY > posY and targetY < posY + sizeY then
            currentBoxColor= targetBoxColor
            currentTextColor= targetTextColor
            if isKeyJustPressed(VK_LBUTTON) then bool= true end
        end
    
        renderDrawBox(posX, posY, sizeX + 2, sizeY, currentBoxColor)
        renderFontDrawText(d3dFont, Title, posX, posY, currentTextColor)
        return bool
    end
     
  5. 4el0ve4ik

    4el0ve4ik Дилер картошки
    Друг

    Регистрация:
    12.11.2015
    Сообщения:
    1.327
    Симпатии:
    399
    Репутация:
    102
    Описание: поиск пикапа по его ID
    Использование:
    function main()
    if isKeyDown(66) and isKeyJustPressed(72) then
    while isKeyDown(66) or isKeyDown(72) do
        wait(10)
    end
    pickupid()
    end
    if resultpick then
    --body
    end
    end
    Код:
    
    function pickupid(model)
       local poolPtr = sampGetPickupPoolPtr()
       local ptwo = readMemory(poolPtr, 4, 0)
       if ptwo > 0 then
         ptwo = poolPtr + 0x4
         local pthree = poolPtr + 0xF004
         for id = 1, 4096 do
           local pfive = readMemory(ptwo + id * 4, 4, false)
           if pfive < 0 or pfive > 0 then
             pfive = readMemory(pthree + id * 20, 4, false)
             if pfive == model then
               return id
             end
           end
         end
       end
    end
    
     
    #5 4el0ve4ik, 5 сен 2016
    Последнее редактирование модератором: 6 сен 2016
  6. FYP

    FYP админ какой-то

    Регистрация:
    09.03.2013
    Сообщения:
    1.113
    Симпатии:
    1.959
    Репутация:
    736
    Описание: разбивает цвет, представленный в виде целого, на составляющие (alpha, red, green, blue)
    Код:
    
    function explode_argb(argb)
      local a = bit.band(bit.rshift(argb, 24), 0xFF)
      local r = bit.band(bit.rshift(argb, 16), 0xFF)
      local g = bit.band(bit.rshift(argb, 8), 0xFF)
      local b = bit.band(argb, 0xFF)
      return a, r, g, b
    end
    
    Описание: обратная операция - конвертирует цвет alpha, red, green, blue в целое
    Код:
    
    function join_argb(a, r, g, b)
      local argb = b  -- b
      argb = bit.bor(argb, bit.lshift(g, 8))  -- g
      argb = bit.bor(argb, bit.lshift(r, 16)) -- r
      argb = bit.bor(argb, bit.lshift(a, 24)) -- a
      return argb
    end
    
    Пример:
    
    -- функция преобразует цвет ARGB, представленный в виде целого в RGBA в виде целого
    function argb_to_rgba(argb)
      local a, r, g, b = explode_argb(argb)
      return join_argb(r, g, b, a)
    end
    
    print(bit.tohex(argb_to_rgba(0x11223344)))
    -- будет выведено 0x22334411
    
     
    RedBoxWhite и 4el0ve4ik нравится это.
  7. FYP

    FYP админ какой-то

    Регистрация:
    09.03.2013
    Сообщения:
    1.113
    Симпатии:
    1.959
    Репутация:
    736
    
    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
    
    ))
     
    4el0ve4ik и Шелди нравится это.
  8. 4el0ve4ik

    4el0ve4ik Дилер картошки
    Друг

    Регистрация:
    12.11.2015
    Сообщения:
    1.327
    Симпатии:
    399
    Репутация:
    102
    Функция позволяет узнать сколько патронов в обойме.
    
    function getAmmoInClip()
      local struct = getCharPointer(playerPed)
      local prisv = struct + 0x0718
      local prisv = memory.getint8(prisv, false)
      local prisv = prisv * 0x1C
      local prisv2 = struct + 0x5A0
      local prisv2 = prisv2 + prisv
      local prisv2 = prisv2 + 0x8
      local ammo = memory.getint32(prisv2, false)
      return ammo
    end
    
    Использование:
    local ammoinclip = getAmmoInClip()
    P.S.
    local memory = require "memory"
    в начало кода пропишите.
     
    Devilupa нравится это.
  9. hnnssy

    hnnssy Creator of mgmoldova's mother
    Друг

    Регистрация:
    23.03.2013
    Сообщения:
    1.817
    Симпатии:
    1.110
    Репутация:
    187
    Получение серийника логического диска.
    local ffi = require("ffi")
    ffi.cdef[[
    int __stdcall GetVolumeInformationA(
        const char* lpRootPathName,
        char* lpVolumeNameBuffer,
        uint32_t nVolumeNameSize,
        uint32_t* lpVolumeSerialNumber,
        uint32_t* lpMaximumComponentLength,
        uint32_t* lpFileSystemFlags,
        char* lpFileSystemNameBuffer,
        uint32_t nFileSystemNameSize
    );
    ]]
    local serial = ffi.new("unsigned long[1]", 0)
    ffi.C.GetVolumeInformationA(nil, nil, 0, serial, nil, nil, nil, 0)
    serial = serial[0]
     
    romacaddy, 4el0ve4ik и Garrus нравится это.
  10. hnnssy

    hnnssy Creator of mgmoldova's mother
    Друг

    Регистрация:
    23.03.2013
    Сообщения:
    1.817
    Симпатии:
    1.110
    Репутация:
    187
    Описание: Рисует полосу и числовое значение с указанными параметрами. (как бары в hCHUD, например)
    Использование: drawBar(posX, posY, sizeX, sizeY, color1, color2, borderThickness, font, value)
    Код:
    
    function drawBar(posX, posY, sizeX, sizeY, color1, color2, borderThickness, font, value)
       renderDrawBoxWithBorder(posX, posY, sizeX, sizeY, color2, borderThickness, 0xFF000000)
       renderDrawBox(posX + borderThickness, posY + borderThickness, sizeX / 100 * value - (borderThickness * 2), sizeY - (2 * borderThickness), color1)
       local textLenght = renderGetFontDrawTextLength(font, tostring(value))
       local textHeight = renderGetFontDrawHeight(font)
       renderFontDrawText(font, tostring(value), posX + (sizeX / 2) - (textLenght / 2), posY + (sizeY / 2) - (textHeight / 2), 0xFFFFFFFF)
    end
    
    Пример:
    HPbar
     
    ИтеС, FYP, 4el0ve4ik и ещё 1-му нравится это.
  11. hnnssy

    hnnssy Creator of mgmoldova's mother
    Друг

    Регистрация:
    23.03.2013
    Сообщения:
    1.817
    Симпатии:
    1.110
    Репутация:
    187
    Описание: Рисует кликабельный текст (как в hClickCommands).
    Использование: if drawClickableText(font, text, posX, posY, color, colorA) then -- colorA - цвет текста при наведении курсора
    Код:
    
    function drawClickableText(font, text, posX, posY, color, colorA)
       renderFontDrawText(font, text, posX, posY, color)
       local textLenght = renderGetFontDrawTextLength(font, text)
       local textHeight = renderGetFontDrawHeight(font)
       local curX, curY = getCursorPos()
       if curX >= posX and curX <= posX + textLenght and curY >= posY and curY <= posY + textHeight then
         renderFontDrawText(font, text, posX, posY, colorA)
         if wasKeyPressed(1) then
           return true
         end
       end
    end
    
    Пример: (возле игроков рисует 2 кликлинка для отправки сообщения и репорта)
    https://pp.vk.me/c836537/v836537950/22914/kn-I3j-c5Uk.jpg

    script_name("drawClickableText")
    script_description("example of using drawClickableText function")
    script_version_number(1)
    script_version("v.001")
    script_authors("hnnssy")
    
    local ffi = require "ffi"
    local getBonePosition = ffi.cast("int (__thiscall*)(void*, float*, int, bool)", 0x5E4280)
    
    function main()
        if not isSampfuncsLoaded() or not isSampLoaded() then return end
        while not isSampAvailable() do wait(100) end
        local font = renderCreateFont("Tahoma", 8, 5)
        while true do
            wait(0)
            if not isPauseMenuActive() and isPlayerPlaying(playerHandle) then
                if wasKeyPressed(90) then
                    while isKeyDown(90) do
                        wait(0)
                        sampToggleCursor(1)
                        for id = 0, sampGetMaxPlayerId(true) do
                             if sampIsPlayerConnected(id) then
                            local exists, handle = sampGetCharHandleBySampPlayerId(id)
                                if exists and isCharOnScreen(handle) then
                                    plX, plY, plZ = getBodyPartCoordinates(8, handle)
                                    local plsX, plsY = convert3DCoordsToScreen(plX, plY, plZ)
                                    if drawClickableText(font, "send message", plsX + 25, plsY, 0xFFFFFFFF, 0xFFFF0000) then
                                        sendMessage(id)
                                    end
                                    if drawClickableText(font, "send report", plsX + 25, plsY + 15, 0xFFFFFFFF, 0xFFFF0000) then
                                        sendReport(id)
                                    end
                                end
                            end
                        end
                    end
                    if wasKeyReleased(90) then sampSetCursorMode(0) end
                end
            end
        end
    end
    
    function sendMessage(id)
    sampSetChatInputEnabled(1)
    sampSetChatInputText("/pm " .. id .. " ")
    end
    
    function sendReport(id)
    sampSetChatInputEnabled(1)
    sampSetChatInputText("/report " .. id .. " ")
    end
    
    function getBodyPartCoordinates(id, handle)
      local pedptr = getCharPointer(handle)
      local vec = ffi.new("float[3]")
      getBonePosition(ffi.cast("void*", pedptr), vec, id, true)
      return vec[0], vec[1], vec[2]
    end
    
    function drawClickableText(font, text, posX, posY, color, colorA)
        renderFontDrawText(font, text, posX, posY, color)
        local textLenght = renderGetFontDrawTextLength(font, text)
        local textHeight = renderGetFontDrawHeight(font)
        local curX, curY = getCursorPos()
          if curX >= posX and curX <= posX + textLenght and curY >= posY and curY <= posY + textHeight then
            renderFontDrawText(font, text, posX, posY, colorA)
            if wasKeyPressed(1) then
                return true
            end
        end
    end
    
     
    Последние данные очков репутации:
    FYP: 3 Очки (хоть что-то годное) 12 фев 2017
    #11 hnnssy, 12 фев 2017
    Последнее редактирование: 13 фев 2017
    romacaddy, ИтеС, Bogach и ещё 1-му нравится это.
  12. Jesik

    Друг

    Регистрация:
    19.03.2013
    Сообщения:
    565
    Симпатии:
    161
    Репутация:
    175
    Описание: Расстояние между точки "А" в 3D пространстве до точки "B"
    distance= math.sqrt( ((posX-pedX)^2) + ((posY-pedY)^2) + ((posZ-pedZ)^2))
    Пример использования:
    
    posX,posY,posZ = 0,0,0
    pedX,pedY,pedZ = getCharCoordinates(playerPed)
    distance= math.sqrt( ((posX-pedX)^2) + ((posY-pedY)^2) + ((posZ-pedZ)^2))
    print(distance)
    
    Знаю что это простая математическая формула. Ну вдруг кому пригодится
     
    Последние данные очков репутации:
    4el0ve4ik: 2 Очки (твоя математика похвальна, но есть уже встроенная) getDistanceBetweenCoords3d) 11 мар 2017
    Losyash1337 и 4el0ve4ik нравится это.
  13. Losyash1337

    Losyash1337 Пользователь

    Регистрация:
    03.01.2017
    Сообщения:
    16
    Симпатии:
    5
    Репутация:
    0
    Описание: нахождения расстояния между двумя точками на плоскости без math.sqrt с погрешностью 5%.
    Код:
    local function getDistance2d(x1, y1, x2, y2)
        x1 = x1 - x2 -- Далее воспринимаем x1, как dx
        y1 = y1 - y2 -- Далее воспринимаем y1, как dy
    
        if x1 < 0 then x1 = -x1 end -- Модуль dx
        if y1 < 0 then y1 = -y1 end -- Модуль dy
    
        -- Если честно, то тут я что-то недопонимаю,
        -- но работает с погрешнстью .05
        if x1 < y1 then
            return (123 * y1 + 51 * x1) / 128 end
        return (123 * x1 + 51 * y1) / 128
    end


    Описание: нахождения расстояния между двумя точками в пространстве с погрешностью 10%
    Код:
    local function getDistance3d(x1, y1, z1, x2, y2, z2)
        return getDistance2d(z1, z2, getDistance2d(x1, y1, x2, y2), 0)
    end


    Источник: http://www.gamedev.ru/tip/?id=41
    PS: Да, это простая формула, списанная с чьего-то сайтика, но вдруг кому пригодится.
     
  14. SR_team

    SR_team BH Team
    BH Team

    Регистрация:
    26.10.2013
    Сообщения:
    2.668
    Симпатии:
    1.660
    Репутация:
    438
    На сколько я понял, ноги растут из рядов тейлора, а значит 123+51/128 должно быть равно корню из 2. Однако тут немного меньше. Если использовать вместо 123 число 106, а вместо 51 число 74, то погрешность будет меньше. Проверенно на квадрате (dx == dy) с координатами Т1(1;1) и Т2(4;4), где Т1 - первая точка, а Т2 - вторая точка.

    Посчитал. Для квадратов погрешность 0.5%, а для не квадратов менее 2%
     
    #14 SR_team, 13 май 2017
    Последнее редактирование: 13 май 2017
    Losyash1337 и DarkP1xel нравится это.
  15. FYP

    FYP админ какой-то

    Регистрация:
    09.03.2013
    Сообщения:
    1.113
    Симпатии:
    1.959
    Репутация:
    736
    Описание: Универсальная функция для удобной отправки данных синхронизации. Умеет копировать данные локального игрока и игрока по иду. Требует SAMP.Lua.
    
    function samp_create_sync_data(sync_type, copy_from_player)
        local ffi = require 'ffi'
        local sampfuncs = require 'sampfuncs'
        -- from SAMP.Lua
        local raknet = require 'samp.raknet'
        require 'samp.synchronization'
    
        copy_from_player = copy_from_player or true
        local sync_traits = {
            player = {'PlayerSyncData', raknet.PACKET.PLAYER_SYNC, sampStorePlayerOnfootData},
            vehicle = {'VehicleSyncData', raknet.PACKET.VEHICLE_SYNC, sampStorePlayerIncarData},
            passenger = {'PassengerSyncData', raknet.PACKET.PASSENGER_SYNC, sampStorePlayerPassengerData},
            aim = {'AimSyncData', raknet.PACKET.AIM_SYNC, sampStorePlayerAimData},
            trailer = {'TrailerSyncData', raknet.PACKET.TRAILER_SYNC, sampStorePlayerTrailerData},
            unoccupied = {'UnoccupiedSyncData', raknet.PACKET.UNOCCUPIED_SYNC, nil},
            bullet = {'BulletSyncData', raknet.PACKET.BULLET_SYNC, nil},
            spectator = {'SpectatorSyncData', raknet.PACKET.SPECTATOR_SYNC, nil}
        }
        local sync_info = sync_traits[sync_type]
        local data_type = 'struct ' .. sync_info[1]
        local data = ffi.new(data_type, {})
        local raw_data_ptr = tonumber(ffi.cast('uintptr_t', ffi.new(data_type .. '*', data)))
        -- copy player's sync data to the allocated memory
        if copy_from_player then
            local copy_func = sync_info[3]
            if copy_func then
                local player_id
                if copy_from_player == true then
                    local _, player_id = sampGetPlayerIdByCharHandle(PLAYER_PED)
                else
                    player_id = tonumber(copy_from_player)
                end
                copy_func(player_id, raw_data_ptr)
            end
        end
        -- function to send packet
        local func_send = function()
            local bs = raknetNewBitStream()
            raknetBitStreamWriteInt8(bs, sync_info[2])
            raknetBitStreamWriteBuffer(bs, raw_data_ptr, ffi.sizeof(data))
            raknetSendBitStreamEx(bs, sampfuncs.HIGH_PRIORITY, sampfuncs.UNRELIABLE_SEQUENCED, 1)
            raknetDeleteBitStream(bs)
        end
        -- metatable to access sync data and 'send' function
        local mt = {
            __index = function(t, index)
                return data[index]
            end,
            __newindex = function(t, index, value)
                data[index] = value
            end
        }
        return setmetatable({send = func_send}, mt)
    end
    
    Примеры использования:
    
    -- отправка фейковой позиции
    local data = samp_create_sync_data('player')
    data.position.x = 1337
    data.position.y = 1488
    data.position.z = 42
    data.send()
    
    -- отправка синхронизации транспорта по иду с изменением здоровья
    local _, id = sampGetVehicleIdByCarHandle(car)
    local data = samp_create_sync_data('vehicle')
    data.vehicleId = id
    data.position.x, data.position.y, data.position.z = getCarCoordinates(car)
    data.vehicleHealth = 0
    data.send()
    
    -- фейковый выстрел
    local data = samp_create_sync_data('bullet', false)
    data.targetType = 1
    data.targetId = any_player_id
    data.origin.x, data.origin.y, data.origin.z = getActiveCameraCoordinates()
    data.target.x, data.target.y, data.target.z = target_x, target_y, target_z
    data.weaponId = getCurrentCharWeapon(PLAYER_PED)
    data.send()
    
     
    Последние данные очков репутации:
    A1K8M4: 1 Очко (Божественное спасибо) 26 июл 2017
    #15 FYP, 25 июл 2017
    Последнее редактирование: 26 июл 2017
    olegese, romacaddy, A1K8M4 и ещё 1-му нравится это.
  16. olegese

    olegese Известный пользователь

    Регистрация:
    29.05.2016
    Сообщения:
    50
    Симпатии:
    13
    Репутация:
    7
    Описание: Вычисляет угол(для GTA:SA) между двумя точками
    
    function GetAngleBeetweenTwoPoints(x1,y1,x2,y2)
      local plus = 0.0
        local mode = 1
        if x1 < x2 and y1 > y2 then plus = math.pi/2; mode = 2; end
        if x1 < x2 and y1 < y2 then plus = math.pi; end
        if x1 > x2 and y1 < y2 then plus = math.pi*1.5; mode = 2; end
        local lx = x2 - x1
        local ly = y2 - y1
        lx = math.abs(lx)
        ly = math.abs(ly)
        if mode == 1 then ly = ly/lx;
        else ly = lx/ly; end
        ly = math.atan(ly)
        ly = ly + plus
        return ly
    end
    
    Пример использования:
    
            px, py, _ = getCharCoordinates(playerPed)
            angle = GetAngleBeetweenTwoPoints(px,py,0,0)
            setCameraPositionUnfixed(0.0,angle)
            -- Камера будет направленна на точку с координатами 0 0 0
    
     
    #16 olegese, 21 авг 2017
    Последнее редактирование: 21 авг 2017
    romacaddy нравится это.