Skip to content

Callbacks example

on_paint - callback

local function draw()
  -- draw something
end
client.add_callback("on_paint", draw)
create_move - callback
local function createmove_func(cmd)
  -- do something
end
client.add_callback("create_move", createmove_func)
on_shot - callback
local function shot(shot_info)
  local result = shot_info.result
  if result == "Hit" then
    client.log("Hitted")
  end
end
client.add_callback("on_shot", shot)

Register event

local function hurt(event)
-- some code
end

events.register_event("player_hurt", hurt)

Manipulation of the panorama

panorama.run_script([[
    mainMenuSpinbot = undefined
    mainMenuRainbow = undefined
    vanityPanel.SetDirectionalLightAmount(0);
]])

panorama.run_script([[
    var vanityPanel = $.GetContextPanel().GetChild(0).FindChildInLayoutFile( 'JsMainmenu_Vanity' );

    var menuSpinbotDegrees = 0;
    var menuSpinbotSpeed = 1

    function mainMenuSpinbot() {
        menuSpinbotDegrees += menuSpinbotSpeed / 10;

        if (menuSpinbotDegrees > 360) {
            menuSpinbotDegrees = menuSpinbotDegrees - 360;
        }

        vanityPanel.SetSceneAngles(0, menuSpinbotDegrees, 0, 0)

        $.Schedule(0.01, mainMenuSpinbot)
    }

    var mainMenuRainbowEnabled = false;
    var rainbowSpeed = 0;
    var r = 0.0;
    var g = 0.0;
    var b = 0.0;
    var x = 0.0;
    var y = 0.0;

    function mainMenuRainbow() {
        if (rainbowSpeed > 0) {
            if( y >= 0 && y < 255 ) {
                r = 255;
                g = 0;
                b = x;
            } else if( y >= 255 && y < 510 ) {
                r = 255 - x;
                g = 0;
                b = 255;
            } else if( y >= 510 && y < 765 ) {
                r = 0;
                g = x;
                b = 255;
            } else if( y >= 765 && y < 1020 ) {
                r = 0;
                g = 255;
                b = 255 - x;
            } else if( y >= 1020 && y < 1275 ) {
                r = x;
                g = 255;
                b = 0;
            } else if( y >= 1275 && y < 1530 ) {
                r = 255;
                g = 255 - x;
                b = 0;
            }

            x+=rainbowSpeed;
            if( x >= 255 )
                x = 0;

            y+=rainbowSpeed;
            if( y > 1530 ) {
                y = 0;
            }

            vanityPanel.SetAmbientLightColor(r, g, b);
        }
        $.Schedule(0.01, mainMenuRainbow)
    }

    mainMenuRainbow();
    mainMenuSpinbot();
]])

panorama.run_script([[menuSpinbotSpeed = 50;]])
panorama.run_script([[rainbowSpeed  = 1;]])

Draw triangle

local function draw()
  render.draw_triangle(100, 100, 120, 90, 80, 90, color.new(255, 0, 0))
end

client.add_callback("on_paint", draw)

Render images

local data = http.post("url") or file.read("path")
local texture = render.create_image(data)

local function draw()
  render.draw_image(x,y,x2,y2,texture)
end
client.add_callback("on_paint", draw)

Find signature

local ffi = require("ffi")

ffi.cdef[[
    typedef struct  {
        float x;
        float y;
        float z;
    } vec3_t;

    struct beam_info_t {
        int     m_type;
        void* m_start_ent;
        int     m_start_attachment;
        void* m_end_ent;
        int     m_end_attachment;
        vec3_t      m_start;
        vec3_t      m_end;
        int     m_model_index;
        const char  *m_model_name;
        int     m_halo_index;
        const char  *m_halo_name;
        float       m_halo_scale;
        float       m_life;
        float       m_width;
        float       m_end_width;
        float       m_fade_length;
        float       m_amplitude;
        float       m_brightness;
        float       m_speed;
        int     m_start_frame;
        float       m_frame_rate;
        float       m_red;
        float       m_green;
        float       m_blue;
        bool        m_renderable;
        int     m_num_segments;
        int     m_flags;
        vec3_t      m_center;
        float       m_start_radius;
        float       m_end_radius;
    } ;

    typedef void (__thiscall* draw_beams_t)(void*, void*);
    typedef void*(__thiscall* create_beam_points_t)(void*, struct beam_info_t&);
]]

local render_beams_signature = "B9 ? ? ? ? A1 ? ? ? ? FF 10 A1 ? ? ? ? B9"
local match = utils.find_signature("client.dll", render_beams_signature)
local render_beams = ffi.cast('void**', ffi.cast("char*", match) + 1)[0] 
local render_beams_class = ffi.cast("void***", render_beams)
local render_beams_vtbl = render_beams_class[0]

local draw_beams = ffi.cast("draw_beams_t", render_beams_vtbl[6])
local create_beam_points = ffi.cast("create_beam_points_t", render_beams_vtbl[12])

local get_eye = function()
    local lc = entitylist.get_local_player()
    local origin = lc:get_origin()
    local offset = entitylist.get_local_player():get_prop_float("CBasePlayer", "m_vecViewOffset[2]")
    return { origin.x, origin.y, origin.z + offset }
end

local bor = bit.bor
local new = ffi.new

local function create_beams(startpos, red, green, blue, alpha)
    local beam_info = new("struct beam_info_t")
    beam_info.m_type = 0x00
    beam_info.m_model_index = -1
    beam_info.m_halo_scale = 0

    beam_info.m_life = 2
    beam_info.m_fade_length = 1

    beam_info.m_width = 20 * .1
    beam_info.m_end_width = 20 * .1

    beam_info.m_model_name = "sprites/purplelaser1.vmt"    

    beam_info.m_amplitude = 2.3
    beam_info.m_speed = 0.2

    beam_info.m_start_frame = 0
    beam_info.m_frame_rate = 0

    beam_info.m_red = red 
    beam_info.m_green = green
    beam_info.m_blue = blue
    beam_info.m_brightness = alpha

    beam_info.m_num_segments = 2
    beam_info.m_renderable = true

    beam_info.m_flags = bor(0x00000100 + 0x00000200 + 0x00008000)

    beam_info.m_start = startpos
    beam_info.m_end = get_eye() 

    local beam = create_beam_points(render_beams_class, beam_info) 
    if beam ~= nil then 
        draw_beams(render_beams, beam)
    end
end

events.register_event("bullet_impact", function(e)
    if engine.get_player_for_user_id(e:get_int("userid")) == engine.get_local_player_index() then 
        local r,g,b,a = 255,255,255,255
        create_beams({e:get_int("x"), e:get_int("y"), e:get_int("z")}, r, g, b, a)
    end
end)

Drawmodel example

local mat_data = [[
    {
        "$basetexture" "vgui/white_additive"
        "$nocull" "1"
        "$nofog" "1"
        "$model" "1"
        "$nocull" "0"
        "$phong" "1"
        "$phongboost" "0"
        "$basemapalphaphongmask" "1"
        "$pearlescent" "6"
    }
]]

local mat = material.create("ts",mat_data,false)

menu.add_color_picker("mat clr")

local function drawmodel(model)
        local clr = menu.get_color("mat clr")
        model:set_blend(clr:a())
        model:color_modulate(clr,mat)
        model:force_material(mat)
        model:draw_extra_pass()
end

client.add_callback("drawmodel", drawmodel)