User File #638378346692955946

Upload All User Files

#638378346692955946 - Jets'n'Guns Gold (Linux Steam) overlay script

jets.lua
System: Linux
54 downloads
Uploaded 12/10/2023 7:51 PM by r57shell (see all 21)
function u32(addr)
    return memory.readu32(addr)
end

function s32(addr)
    return memory.reads32(addr)
end

function u8(addr)
    return memory.readu8(addr)
end

function float(addr)
    return memory.readf(addr)
end

--[[
set *(int*)0x809a094 = 800
set *(int*)0x809a09c = 600
set *(int*)0x809a0c7 = 0x90909090
set *(char*)0x809a0cb = 0x90
]]

local ortho_left = -200
local ortho_right = 1000
local ortho_top = -150
local ortho_bottom = 750
local screen_width = 1024
local screen_height = 768

--[[local ortho_left = 0
local ortho_right = 800
local ortho_top = 0
local ortho_bottom = 600
local screen_width = 800
local screen_height = 600]]


function gui_rectangle(x, y, w, h, s, c1, c2)
    gui.rectangle(
        math.floor((x - ortho_left) * screen_width / (ortho_right - ortho_left)),
        math.floor((y - ortho_top) * screen_height / (ortho_bottom - ortho_top)),
        math.floor(w * screen_width / (ortho_right - ortho_left)),
        math.floor(h * screen_height / (ortho_bottom - ortho_top)),
        s, c1, c2)
end

function gui_text(x, y, s, c1, c2)
    gui.text(
        math.floor((x - ortho_left) * screen_width / (ortho_right - ortho_left)),
        math.floor((y - ortho_top) * screen_height / (ortho_bottom - ortho_top)),
        s, c1, c2)
end

-- 80715b1
-- eax = triggers
-- 2 drop duck
-- 3 ?
-- 79 - message hull integrity 25%
-- 7a - message hull integrity 50%
-- 7b - message hull integrity 100%
-- 7d - message no heating 20 secs
-- 7e - message immortality 10 secs
-- 7f - message 4 x fire power 20 secs
-- 80 - message extra cash $2500
-- 81 - message extra cash $5000
-- 82 - message extra cash $10000
-- 83 - drop hull
-- 84 - drop hull
-- 85 - drop hull
-- 86 - drop hull
-- 87 - drop hull
-- 88 - drop $2500
-- 89 - drop $
-- 8a - drop $
-- 8b - drop $
-- 8c - drop chest
-- 8d - drop chest
-- 8e - drop chest
-- 8f - drop chest
-- 90 - drop cooldown
-- 91 - drop x4 fire 20 secs
-- 92 - drop round disc
-- 93 - white flash on whole screen
-- 94 - 

-- AC - flame explosion
-- F0 explode with parts level 1
-- F1 explode with parts level 1

function drawcollision(col, color1, color2)
    local cnt = math.min(s32(col + 0xac), 10)
    if cnt > 0 then
        local scalex = float(col + 0x54)
        local scaley = float(col + 0x58)
        local posx = float(col + 0x8)
        local posy = float(col + 0xC)
        for i = 0, cnt - 1 do
            local x1 = math.floor(posx + scalex * s32(col + 0x6c + i * 0x10))
            local y1 = math.floor(posy + scaley * s32(col + 0x70 + i * 0x10))
            local x2 = math.floor(posx + scalex * s32(col + 0x74 + i * 0x10))
            local y2 = math.floor(posy + scaley * s32(col + 0x78 + i * 0x10))
            gui_rectangle(x1, y1, x2 - x1, y2 - y1, 0, color1, color2)
        end
    end
end

function coords(enemy, idx, idx1, idx2)
    --local state = u32(enemy + 0x3c)
    --if state ~= 1 then return end
    local field_18 = u32(enemy + 0x18)
    local score = u32(field_18 + 10 * 4)
    --if score == 0 then return end
    local width = 5
    local height = 5
    local field_1C = u32(enemy + 0x1C)
    if s32(field_1C + 0xac) <= 0 then return end -- have collision check
    local field_1Cv = u32(field_1C)
    if field_1Cv ~= 0 then
        width = math.floor(s32(field_1Cv + 4) * float(field_1C + 21 * 4))
        height = math.floor(s32(field_1Cv + 8) * float(field_1C + 22 * 4))
    end
    local screenx = float(field_1C + 2 * 4)
    local screeny = float(field_1C + 3 * 4)
    local field_14 = u32(enemy + 0x14)
    if u32(field_14 + 0xAC) ~= 0 then
        score = score * 5
    end
    local hp = s32(enemy + 0x38)
    local color = 0x55FFFFFF
    local drawbox = true
    local addr = field_14
    --[[local name
    if addr ~= 0 then
        addr = u32(addr)
        if addr ~= 0 then
            name = ''
            for i = 0, 47 do
                local c = u8(addr + i)
                if c == 0 then
                    break
                end
                name = name .. string.char(c)
            end
            if name ~= '' then
                --gui_text(math.floor(screenx), math.floor(screeny), string.format("%s", name))
            end
        end
    end]]
    local random_delay = float(field_14 + 0x11c)
    local enemyDef = u32(field_14)
    local man = u32(enemyDef + 0xa4)
    if man == 1 then
        drawcollision(field_1C, 0x00000000, 0x60FF00FF)
        mans = mans + 1
    else
        drawcollision(field_1C, 0x00000000, 0x600000FF)
    end
    if score > 0 then
        color = 0xFFFF0000
        --gui_rectangle(math.floor(screenx), math.floor(screeny), math.floor(screenx + width) - math.floor(screenx), math.floor(screeny + height) - math.floor(screeny), 1, color, 0x00000000)
        if hp > 0 then
            if u32(field_14 + 0xac) ~= 0 then -- pirate
                gui_text(math.floor(screenx), math.floor(screeny), string.format("%d", hp), 0xFF00FF00)
            else
                --gui_text(math.floor(screenx), math.floor(screeny), string.format("%.0f", random_delay/0.016666))
                gui_text(math.floor(screenx), math.floor(screeny), string.format("%d %.0f %d", hp, random_delay/0.016666, score))
            end
        end
    --elseif float(field_14 + 0x74) <= 0 and string.sub(name, 0, 6) == 'b_cash' then
    elseif enemyDef ~= 0 and float(enemyDef + 0x70) > 0 then -- bonus
        gui_rectangle(math.floor(screenx), math.floor(screeny), math.floor(screenx + width) - math.floor(screenx), math.floor(screeny + height) - math.floor(screeny), 3, 0xFF00FF00, 0x00000000)
    else
        if hp > 0 and hp ~= 999999 then
            gui_rectangle(math.floor(screenx), math.floor(screeny), math.floor(screenx + width) - math.floor(screenx), math.floor(screeny + height) - math.floor(screeny), 1, color, 0x00000000)
            gui_text(math.floor(screenx), math.floor(screeny), string.format("%d", hp))
        end
    end
    --gui_text(math.floor(screenx), math.floor(screeny), string.format("%x %d %d %d", enemy, idx, idx1, idx2))
    --if drawbox then
    --end
    if hp > 0 and score > 0 then
       -- gui_text(math.floor(screenx), math.floor(screeny), string.format("%d", hp))
    end
    --print(string.format("%x: %.5f %.5f %d", enemy, screenx, screeny, score))
    --print(string.format("%x: %d %d %d", enemy, idx, idx1, idx2))
end


function findWhoGotHit(a0, idx, idx1) -- 8073140
    --print(string.format("local list %x", a0))
    local ptr = u32(a0 + 0x1C)
    local arr, cnt, enemy, i
    cnt = s32(ptr)
    if cnt > 100000 then
        cnt = 100000
    end
    if cnt > 0 then
        arr = u32(ptr + 4)
        --print(string.format("%x arr %x", a0, arr))
	if arr ~= 0 then
            for i = 0, cnt - 1 do
                enemy = u32(arr + i * 4)
                if enemy ~= 0 then
                    --print(string.format("enemy %x", enemy))
                    coords(enemy, idx, idx1, i)
	        end
	    end
        end
    end
end


function checkGlobalList(addr, idx)
    local lvlSmth = u32(addr)
    if lvlSmth == 0 then
        return
    end
    --print(string.format("global list %x", addr))
    local list = u32(lvlSmth + 4)
    for i = 1, 100 do
        if list == 0 then
	    break
	end
        findWhoGotHit(list, idx, i)
	list = u32(list + 0x160)
    end
end

function checkLayer(layer, idx)
    --print(string.format("%d %x", idx, layer))
    if u32(layer + 0x34) == 0 then return end
    local layerPosX = float(layer + 0x85058)
    local layerPosY = float(layer + 0x8505C)
    --print(string.format("x=%f y=%f %d %d %d %d", layerPosX, layerPosY, s32(layer + 0x48), s32(layer + 0x4C), s32(layer + 0x50), s32(layer + 0x54)))
    for idx2 = s32(layer + 0x4c), s32(layer + 0x54) - 1 do
        for idx = s32(layer + 0x48), s32(layer + 0x50) - 1 do
            local offs = u32(layer + idx2 * 4 + 0x58 + idx * 0x200)
            if offs ~= 0 then
                local offs1 = u32(offs + 0xC0)
                if offs1 ~= 0 then
                    local score = s32(offs1 + 0xB4)
                    if score ~= 0 then
                        --print(string.format("offs=%x offs1=%x %d", offs, offs1, score))
                        local tilePosX = s32(offs + 0xD8) - math.floor(layerPosX)
                        local tilePosY = s32(offs + 0xDC) - math.floor(layerPosY)
                        local offs2 = u32(offs)
                        local width = 5
                        local height = 5
                        if offs1 ~= 0 then
                            width = s32(offs2 + 4)
                            height = s32(offs2 + 8)
                        end
                        --print(string.format("%d %d %d %d", tilePosX, tilePosY, width, height))
                        local hp = s32(offs + 0xe0)
                        gui_rectangle(tilePosX, tilePosY, width, height, 1, 0xFF00FFFF, 0x00000000)
                        gui_text(math.floor(tilePosX), math.floor(tilePosY), string.format("%.0f", hp))
                    end
                end
            end
        end
    end
end

function checkLayers()
    local layers = u32(0x80e3f5c)
    local layersCount = s32(layers)
    for i = 0, layersCount - 1 do
        local arr = u32(layers + 4)
        if arr ~= 0 then
            local layer = u32(arr + i * 4)
            if layer ~= 0 then
                checkLayer(layer, i)
            end
        end
    end
end

-- 80B6900
-- 806DCE0 - register kill

function u321(addr)
    local v = u32(addr)
    if v == nil then v = 0 end
    --print('get', v)
    return v
end

--[[
body counter bonuses

>= 5 MULTI KILL 250
>= 10   500 ratio 50
>= 20   1000 ratio 50
>= 30   2500 ratio 83.333333
>= 45   5000 ratio 111.111111
>= 60   7500 ratio 125
]]

function listWeapon(weapon, index, posy)
    local weaponType = u32(weapon)
    local name = ''
    for i = 0, 0x2f do
        local code = u8(weaponType + 4 + i)
        if code == 0 then break end
        name = name .. string.char(code)
    end
    local level = u32(weapon + 0xc)
    local ammo = s32(weapon + 0x18)
    local reloadTimer = float(weapon + 0x1c)
    local streamList = u32(weapon + 0x8)
    local streamCnt = 0
    local streamAddr = 0
    if streamList ~= 0 then
        streamCnt = u32(streamList)
        streamAddr = u32(streamList + 4)
        if streamAddr == 0 then
            streamCnt = 0
        end
    end
    --gui_text(50, posy, string.format("%d %s lvl=%d streams=%d ammo=%d %.1f", index, name, level, streamCnt, ammo, reloadTimer * 60))
    local posyb = posy
    posy = posy + 15
    local dps = 0
    for i = 0, streamCnt - 1 do
        local stream = u32(streamAddr + 4 * i)
        if stream ~= 0 then
            local streamType = u32(stream)
            if streamType ~= 0 then
                local state = s32(streamType + level * 4 + 0xd8)
                if state > 0 then
                    local power = s32(streamType + level * 4 + 0x100)
                    local shot_delay = float(streamType + level * 4 + 0x128)
                    local cooldown = float(stream + 4)
                    gui_text(65, posy, string.format("%d %.0f %.5f", power, cooldown * 60, shot_delay))
                    posy = posy + 15
                    dps = dps + power / math.ceil(shot_delay * 60 - 1e-6)
                end
            end
        end
    end
    gui_text(50, posyb, string.format("%s %d %.2f %d %.0f", name, level, dps, ammo, reloadTimer * 60))
    return posy
end

function listWeapons(player)
    local weaponsList = u32(player + 0x244)
    if weaponsList == 0 then return end
    local posy = 60
    local cnt = s32(weaponsList)
    if cnt >= 0 then
        local addr = u32(weaponsList + 4)
        if addr ~= 0 then
            for i = 0, cnt - 1 do
                local weapon = u32(addr + 4 * i)
                if weapon ~= 0 then
                    posy = listWeapon(weapon, i, posy)
                end
            end
        end
    end
end

function onPaint()
    local player = u32(0x80e492c)
    if player == 0 then return end
    listWeapons(player)
    local posx = float(player + 0x8)
    local posy = float(player + 0xc)
    drawcollision(player, 0x8000ffff, 0x8000ffff)
    local hull_now = float(player + 0x104)
    local hull_max = s32(player + 0x100)
    local heat_now = float(player + 0x1f4)
    local heat_max = s32(player + 0x1f0)
    local body_acc = s32(player + 0x288)
    local body_del = float(player + 0x28c)
    local menu = u32(0x80e326c)
    local atarix = u32(menu + 0xd0)
    code = 0
    if atarix ~= 0 then
        for i = 0, 3 do
            code = code * 10 + s32(atarix + 0xb4 + i * 4)
        end
    end
    --[[local cursor = u32(menu + 0x884)
    local cursorX = -999
    local cursorY = -999
    if cursor ~= 0 then
        cursorX = float(cursor + 0xC0)
        cursorY = float(cursor + 0xC4)
    end]]
    mans = 0
    gui_text(120, 0, string.format("money: %d menu: %d %d %04d", u32(player + 0x10C), s32(menu + 0x86c), s32(menu + 0x5d0), code))
    gui_text(120, 15, string.format("hull %d/%d %.1f%%", hull_now, hull_max, hull_now * 100 / math.max(hull_max, 1)))
    gui_text(120, 30+200*0, string.format("heat %.1f/%d %.1f%% %d %.3f (%.2f %.2f)", heat_now, heat_max, heat_now * 100 / math.max(heat_max, 1), body_acc, body_del, posx, posy))
    --gui_text(120, 45, string.format("%x %x %x %x %x", u321(0x811780c), u321(u321(0x811780c)+0xd0), u321(0x0811780c), u321(0x0811780c)+0xbc, u321(u321(0x0811780c)+0xbc)))
    --print("===================")
    for i = 0, 2 do
        checkGlobalList(0x80e497c + 4 * i, i)
    end
    gui_text(120, 45+200*0, string.format("mans %d", mans))
    checkLayers()
    gui_rectangle(0, 0, 800, 600, 1, 0xFFFF00FF, 0)
end

--print("===================")
--onPaint()

print(onPaint)
callback.onPaint(onPaint)