SA:MP Lua HUD [Lua] AnimatedHPBars - исходник анимированных баров

lifeforassembly

Новичок
Автор темы
3
4
Версия SA-MP
  1. Любая
Декодированный исходник скрипта AnimatedHPBars от Winstalio.

Дело было вечером, делать было нечего.
Оригинал был обфусцирован через LuaJIT 2.0 bytecode, код зашифрован перевёрнутыми ASCII-кодами в массиве из 7228 чисел. Схема примитивная, каждый символ исходника преобразован через reverse(tostring(char_code)) и упакован в скомпилированный байткод.
Деобфускация выполнена побайтовым парсингом формата LuaJIT bytecode без использования готовых декомпиляторов.

Что делает скрипт:
- Заменяет стандартные полоски HP/брони на анимированные (125 кадров из TXD)
- Плавное изменение HP (lerp)
- Мигание при низком HP
- Поддержка больших баров
- Чтение цветов HP/AP из памяти GTA

Команды:
/hplerp — вкл/выкл плавную анимацию
/hpblink — вкл/выкл мигание при низком HP

Требуется: TXD-файл animatedhpbar.txd с текстурами (125 фреймов + фон)
#FREESCRIPTS
source:
local txdName = "animatedhpbar"
local frameCount = 125
local backgroundTextureNameT = "winstalioz"
local bit = require('bit')
local ffi = require('ffi')

local freymi = {}
local FPS = 70
local InfexFrame = 1
local backgroundTextureT = nil

local inicfg = require 'inicfg'
local directIni = 'hphud.ini'
local ini = inicfg.load(inicfg.load({
    hp = {
        hplerp = true,
        hpblink = true,
    },
}, directIni))
inicfg.save(ini, directIni)

function loadFrames()
    local txdLoaded = loadTextureDictionary(txdName)

    if not txdLoaded then
        print("Ошибка в загрузке TXD файла: " .. txdName)
        return false
    end

    backgroundTextureT = loadSprite(backgroundTextureNameT)
    if backgroundTextureT == 0 then
        print("Ошибка в загрузке текстуры бекграунда: " .. backgroundTextureNameT)
        return false
    end

    for i = 1, frameCount do
        local frameName = string.format('framehp (%d)', i)
        local IDtexture = loadSprite(frameName)
        if IDtexture ~= 0 then
            table.insert(freymi, IDtexture)
        else
            print("Ошибка в загрузке текстуры фрейма: " .. frameName)
        end
    end

    return true
end

local tag = 'AnimBars by {b08fbc}Wi{c396c0}ns{da9ec5}ta{efb4d7}li{efbee1}o {ffffff}| '

function main()
    while not isSampAvailable() do wait(100) end
    sampRegisterChatCommand('hplerp', function()
        ini.hp.hplerp = not ini.hp.hplerp
        inicfg.save(ini)
        sampAddChatMessage(tag .. "Плавное изменение ХП " .. (ini.hp.hplerp and 'активировано!' or 'деактивировано!'), -1)
    end)
    sampRegisterChatCommand('hpblink', function()
        ini.hp.hpblink = not ini.hp.hpblink
        inicfg.save(ini)
        sampAddChatMessage(
            tag .. "Мерцание ХП при низком уровне здоровья " .. (ini.hp.hpblink and 'активировано!' or 'деактивировано!'),
            -1)
    end)
    if not loadFrames() then
        print("Не удалось инициализировать фреймы.")
        return
    end
    lua_thread.create(function()
        wait(2500)
        sampAddChatMessage(tag .. 'loaded.', 0xFFffffff)
    end)

    while true do
        wait(0)
        renderGif()
    end
end

local smoothingSpeed = 0.07

local displayHP, displayAP = 100, 100
local function lerp(a, b, t)
    return a + (b - a) * t
end

local blinkCounter = 0

function renderGif()
    if #freymi > 0 and isHudVisible() then
        local hpbar = ffi.cast('float*', 12030944)[0]
        local bigBars = hpbar > 573
        if bigBars then
            size, APbarOffset, HPbarOffsetY, MaxHP = 0.0534682080924855*(hpbar-569), 2.8, 10, 160
        else
            size, APbarOffset, HPbarOffsetY, MaxHP = 0, 0, 0, 100
        end
        local currentTime = getTickCount()

        local HP = getCharHealth(PLAYER_PED)
        local AP = getCharArmour(PLAYER_PED)

        if ini.hp.hplerp then
            displayHP, displayAP = lerp(displayHP, HP, smoothingSpeed), lerp(displayAP, AP, smoothingSpeed)
        else
            displayHP, displayAP = HP, AP
        end

        InfexFrame = math.floor(currentTime / FPS) % #freymi + 1
        local frames = freymi[InfexFrame]
        local nh, _ = convertGameScreenCoordsToWindowScreenCoords(59.6, 4.5629630088806)
        local barWidthAP = math.min(nh * displayAP / 100 - 2 * 3, nh - 2 * 3)
        local barWidthAP_gameCoords, _ = convertWindowScreenCoordsToGameScreenCoords(barWidthAP, 4.5629630088806)

        local nh, _ = convertGameScreenCoordsToWindowScreenCoords(59.6 + size * 2, 4.5629630088806)
        local barWidthHP = math.min(nh * displayHP / MaxHP - 2 * 3, nh - 2 * 3)
        local barWidthHP_gameCoords, _ = convertWindowScreenCoordsToGameScreenCoords(barWidthHP, 4.5629630088806)

        local offset = barWidthHP_gameCoords / 2


        if HP < 10 and ini.hp.hpblink then
            blinkCounter = blinkCounter + 1
        else
            blinkCounter = 0
        end


        local visible = true
        if HP < 10 and (blinkCounter % 20 < 10) and ini.hp.hpblink then
            visible = false
        end

        local hpBarColorB, hpBarColorG, hpBarColorR = getColorFromMemory(0xBAB22C)
        local hpBarBackColorR, hpBarBackColorG, hpBarBackColorB = darkenColor(hpBarColorR, hpBarColorG, hpBarColorB, 0.1)
        if visible then
            drawBaw(576.5 - size, 67.5 + HPbarOffsetY, hpBarBackColorR, hpBarBackColorG, hpBarBackColorB, 255, size, 0, 0)
            if HP > 3 then
                drawSprite(frames, 548.2 - size * 2 + offset, 67.5 + 3.5 + HPbarOffsetY, barWidthHP_gameCoords, 5,
                    hpBarColorR, hpBarColorG, hpBarColorB, 255)
            end
        end
        local apBarColorB, apBarColorG, apBarColorR = getColorFromMemory(0xBAB23C)
        local apBarBackColorR, apBarBackColorG, apBarBackColorB = darkenColor(apBarColorR, apBarColorG, apBarColorB, 0.1)
        if AP > 0 then
            local offset = barWidthAP_gameCoords / 2
            drawBaw(576.5, 45.5 + APbarOffset, apBarBackColorR, apBarBackColorG, apBarBackColorB, 255, 0,0, 0)
            if AP > 3 then
                drawSprite(frames, 548.2 + offset, 45.5 + 3.5 + APbarOffset, barWidthAP_gameCoords, 5, apBarColorR,apBarColorG, apBarColorB, 255)
            end
        end
    end
end

-- function isHudVisible()
--     return readMemory(12216168, 64, false) == 0x101 and readMemory(5804656, 4, false) == 0x660CEC83 and readMemory(11989075, 4, false) == 1
-- end

function isHudVisible()
    return ffi.cast("int64_t*", 12216168)[0] == 0x101 and ffi.cast("int*", 5804656)[0] == 0x660CEC83 and ffi.cast('int*', 11989075)[0] == 1
end

function drawBaw(posX, posY, colorR, colorG, colorB, alpha, bigSize, width, height)
    drawRect(posX + 0.5, posY + 3.5, 57.6 + bigSize * 2+width*2, 5+height, colorR, colorG, colorB, 255) -- фон
    drawRect(posX, posY-height/2, 60.5 + bigSize * 2+width*2, 2, 0, 0, 0, alpha) -- верхняя полоса
    drawRect(posX, posY + 7+height/2, 60.5 + bigSize * 2+width*2, 2, 0, 0, 0, alpha) -- нижняя полоса
    drawRect(posX + 30.3 + bigSize+width, posY + 3.5, 2, 9+height, 0, 0, 0, alpha) -- правая полоса
    drawRect(posX - 29.3 - bigSize-width, posY + 3.5, 2, 9+height, 0, 0, 0, alpha) -- левая полоса
end

function onScriptTerminate(scr, quit)
    if scr == thisScript() then
        unloadFrames()
    end
end

function unloadFrames()
    freymi = {}
    backgroundTextureT = nil
end

function getTickCount()
    return os.clock() * 1000
end

function getColorFromMemory(address)
    local colorValue = ffi.cast('uint32_t*', address)[0]
    local r = bit.band(bit.rshift(colorValue, 16), 0xFF)
    local g = bit.band(bit.rshift(colorValue, 8), 0xFF)
    local b = bit.band(colorValue, 0xFF)
    local invisible = tonumber(string.format("0x%02X%02X%02X%02X", 0, r, g, b))
    ffi.cast('uint32_t*', address)[0] = invisible
    return r, g, b
end

function darkenColor(r, g, b, factor)
    local darkR = math.floor(r * factor)
    local darkG = math.floor(g * factor)
    local darkB = math.floor(b * factor)
    return darkR, darkG, darkB
end
 

Вложения

  • AnimatedHPBars_decoded.lua
    7.3 KB · Просмотры: 8

Musaigen

ihatemyself
Проверенный
1,708
1,596
 
  • Эм
Реакции: Winstаl