🌐Useful resources

Calculating fov between two points

local function CalculateFov(Start, End, Angle)
    local Direction = (End - Start):normalize()
    local Forward, Right, Up = math.angle_vectors(Angle)
    return math.max(math.deg(math.acos(Forward:dot(Direction))), 0)
end

local fov = CalculateFov(eye_pos, point_in_world, math.vec3(pitch, yaw, 0))

Bit utilities

Setting specific bits

bit.bset = function(number, b, value)
    if value ~= 0 then
        return bit.bor(number, bit.lshift(1, math.log(b, 2)))
    else
        return bit.band(number, bit.bnot(bit.lshift(1, math.log(b, 2))))
    end
end

cmd:set_buttons(bit.bset(cmd:get_buttons(), csgo.in_jump, 1))

FFI utilities

vtable_bind

local function vtable_bind(class, type, index)
    local this = ffi.cast("void***", class)
    local ffi_type = ffi.typeof(type)
    return function (...)
        return ffi.cast(ffi_type, this[0][index])(this, ...)
    end
end
-- Example
local VClientEntityList = utils.find_interface("client.dll", "VClientEntityList003")
local GetClientEntityFN = vtable_bind(VClientEntityList, "void*(__thiscall*)(void*, int)", 3)

local RawLocalPlayer = GetClientEntityFN(engine.get_local_player())

vtable_thunk

local function vtable_thunk(type, index)
    local ffi_type = ffi.typeof(type)
    return function (class, ...)
        local this = ffi.cast("void***", class)
        return ffi.cast(ffi_type, this[0][index])(this, ...)
    end
end

-- Example
local VClientEntityList = utils.find_interface("client.dll", "VClientEntityList003")
local GetClientEntityFN = vtable_thunk("void*(__thiscall*)(void*, int)", 3)

local RawLocalPlayer = GetClientEntityFN(VClientEntityList, engine.get_local_player())

Follow relative x86

Follows relative address and returns the real address

local function Followx86(addr)
    return addr + ffi.cast("uint32_t*", addr + 1)[0] + 5;
end

Credit: Panzerfaust

Misc

Inline hex colors on text

-- backup the original text function for later use
local render_text_og = render.text
local render_get_text_size_og = render.get_text_size

-- turns a color table into a hex string
local function ColorToHex(c)
    return string.format("%02x%02x%02x%02x", c.r, c.g, c.b, c.a)
end

-- redifine text size to ignore inline hex
render.get_text_size = function (id, text)
    local s = text:gsub("\a(%x%x%x%x%x%x%x%x)", "")
    local w, h = render_get_text_size_og(id, s)
    -- fix fucked up font height. you can add more here
    if id == render.font_esp then
        h = h * 0.625
    end
    return w, h
end

-- redefine the render.text function to support rendering inline hex codes
render.text = function(font, x, y, str, color, align_h, align_v)
    -- Done
    if str:len() == 0 then
        return
    end

    if align_h or align_v then
        local txt_w, txt_h = render.get_text_size(font, str)
    
        if align_h == render.align_right then
            x = x - txt_w
        elseif align_h == render.align_center then
            x = x - txt_w / 2
        end

        if align_v == render.align_bottom then
            y = y - txt_h
        elseif align_v == render.align_center then
            y = y - txt_h / 2
        end
    end


    -- Find the first hex pattern
    local Start, End = string.find(str, "\a(%x%x%x%x%x%x%x%x)")
    if Start then
        -- If we have text before the pattern filter it out
        if Start ~= 1 then
            -- Get the string that is before the hex code
            local RenderString = str:sub(0, Start - 1)
            render_text_og(font, x, y, RenderString, color)
            
            -- Add the width to x
            local TextSizeX, TextSizeY = render_get_text_size_og(font, RenderString)
            -- Set our new string to be the start of the hex code aka the \a
            str = str:sub(Start, str:len())
            -- recursion
            render.text(font, x + TextSizeX, y, str, color)
        else
            -- Get the remaining length (used incase there are more hex codes)
            local StringEnd = str:len()
            -- Calculate the render string as if there are no remaining codes
            local RenderString = str:sub(End + 1, StringEnd)
            -- Check if there are more codes
            local SecondSearch, SecondEnd = str.find(RenderString, "\a(%x%x%x%x%x%x%x%x)")

            -- If so set our string to end at the last character before the next code
            -- and set our new end position
            if SecondSearch then
                RenderString = str:sub(End + 1, SecondEnd)
                StringEnd = SecondEnd
            end

            -- Calculate the color from the code
            local HexCode = str:sub(Start + 1, End)
            color = render.color("#" .. HexCode)

            render_text_og(font, x, y, RenderString, color)

            -- Add the width to the x position
            local TextSizeX, TextSizeY = render_get_text_size_og(font, RenderString)
            -- Setup our new string for recursion
            str = str:sub(StringEnd + 1, str:len())
            render.text(font, x + TextSizeX, y, str, color)
        end
    else
        -- No codes were used
        render_text_og(font, x, y, str, color)
    end
end
function on_paint()
    render.text(render.font_esp, x, y, "base color \aff0000ffred", render.color("#FFFFFF"))
end
Example

Fade percentage

--- @param x number 0 - 1
--- @param in_percent number 0 - 1
--- @param out_percent number 0 - 1
--- @return number
math.fade_delta = function(x, in_percent, out_percent)
    if (x > (1 - in_percent)) then
        x = (in_percent - ( x - (1 - in_percent))) / in_percent;
    else
        x = math.min( x * (1 / out_percent), 1.0 );
    end

    return x
end

Last updated