LUA скрипт [GS] smooth localplayer animations

выглядит нормас
 
Обратите внимание, пользователь заблокирован на форуме. Не рекомендуется проводить сделки.
code_language.lua:
Expand Collapse Copy
local ui = require 'wrapper'
local c_entity = require 'gamesense/entity'

local checkbox = ui.create('animation_fix', 'A'):switch('enable animation fix')

local animation_fix do
    animation_fix = {}

    animation_fix.anim_data = {
        layers = {
            [0] = { cycle = 0, weight = 0 }, -- aim_matrix
            [1] = { cycle = 0, weight = 0 }, -- weapon_action
            [2] = { cycle = 0, weight = 0 }, -- weapon_action_recrouch
            [3] = { cycle = 0, weight = 0 }, -- adjust
            [4] = { cycle = 0, weight = 0 }, -- movement_move
            [5] = { cycle = 0, weight = 0 }, -- movement_strafe
            [6] = { cycle = 0, weight = 0 }, -- movement_strafechange
            [7] = { cycle = 0, weight = 0 }, -- whole_body
            [8] = { cycle = 0, weight = 0 }, -- flashed
            [9] = { cycle = 0, weight = 0 }, -- flinch
            [10] = { cycle = 0, weight = 0 }, -- aliveloop
            [11] = { cycle = 0, weight = 0 }, -- jump
            [12] = { cycle = 0, weight = 0 }, -- land
            [13] = { cycle = 0, weight = 0 }, -- move_blend_walk
            [14] = { cycle = 0, weight = 0 }, -- move_blend_run
            [15] = { cycle = 0, weight = 0 }, -- move_blend_crouch
        },
        server_anim_states = {},
        last_sim_time = 0,
        last_velocity = 0,
        last_duck_amount = 0,
        last_weapon = nil,
    }

    local function lerp(a, b, t)
        return a + (b - a) * t
    end

    animation_fix.setup_command = function(cmd)
        if not checkbox:get() then
            return
        end

        local me = entity.get_local_player()
        if not me then
            return
        end

        local self_index = c_entity.new(me)
        local anim_state = self_index:get_anim_state()
        if not anim_state then return end

        local sim_time = globals.servertickcount()
        local vel_x, vel_y = entity.get_prop(me, "m_vecVelocity")
        local velocity = math.sqrt(vel_x * vel_x + vel_y * vel_y)
        local duck_amount = entity.get_prop(me, "m_flDuckAmount")
        local ducking = entity.get_prop(me, "m_bDucking") == 1
        local on_ground = bit.band(entity.get_prop(me, "m_fFlags"), 1) == 1
        local current_weapon = entity.get_player_weapon(me)

        if velocity < 0.1 then
            velocity = 0
        end

        local server_state = {
            time = sim_time,
            layers = {},
            velocity = velocity,
            duck_amount = duck_amount,
            ducking = ducking,
            on_ground = on_ground,
            weapon = current_weapon,
        }

        for layer_idx, _ in pairs(animation_fix.anim_data.layers) do
            local layer = self_index:get_anim_overlay(layer_idx)
            if layer then
                server_state.layers[layer_idx] = {
                    cycle = layer.cycle,
                    weight = layer.weight,
                }
            end
        end

        table.insert(animation_fix.anim_data.server_anim_states, server_state)

        if #animation_fix.anim_data.server_anim_states > 60 then
            table.remove(animation_fix.anim_data.server_anim_states, 1)
        end
    end

    animation_fix.pre_render = function()
        if not checkbox:get() then
            return
        end

        local me = entity.get_local_player()
        if not me then
            return
        end

        local self_index = c_entity.new(me)
        local anim_state = self_index:get_anim_state()
        if not anim_state then return end

        local current_time = globals.realtime()
        local server_states = animation_fix.anim_data.server_anim_states

        if #server_states < 2 then
            return
        end

        local state1, state2
        for i = #server_states - 1, 1, -1 do
            if server_states[i].time <= current_time and server_states[i+1].time >= current_time then
                state1 = server_states[i]
                state2 = server_states[i+1]
                break
            end
        end

        if not state1 or not state2 then
            state1 = server_states[#server_states - 1]
            state2 = server_states[#server_states]
        end

        local t = (current_time - state1.time) / (state2.time - state1.time)
        t = math.min(1, math.max(0, t))

        for layer_idx, _ in pairs(animation_fix.anim_data.layers) do
            local layer = self_index:get_anim_overlay(layer_idx)
            if layer and state1.layers[layer_idx] and state2.layers[layer_idx] then
                local cycle1 = state1.layers[layer_idx].cycle
                local cycle2 = state2.layers[layer_idx].cycle
                local weight1 = state1.layers[layer_idx].weight
                local weight2 = state2.layers[layer_idx].weight

                if (layer_idx == 1 or layer_idx == 2) and state1.weapon ~= state2.weapon then
                    layer.cycle = cycle2
                    layer.weight = weight2
                else
                    layer.cycle = lerp(cycle1, cycle2, t)
                    layer.weight = lerp(weight1, weight2, t)
                end
            end
        end

        local velocity = lerp(state1.velocity, state2.velocity, t)
        local duck_amount = lerp(state1.duck_amount, state2.duck_amount, t)
        local ducking = state1.ducking
        local on_ground = state1.on_ground
        local current_weapon = state1.weapon

        animation_fix.anim_data.last_velocity = velocity
        animation_fix.anim_data.last_duck_amount = duck_amount
        animation_fix.anim_data.last_weapon = current_weapon
    end
end

client.set_event_callback('pre_render', function()
    animation_fix.pre_render()
end)

client.set_event_callback('setup_command', function(cmd)
    animation_fix.setup_command(cmd)
end)

вот ссылка на библиотеку wrapper: https://yougame.biz/threads/339089/
красавчик, теперь время заребилдить серверный лагкомп и адаптировать его под луа апи gamesense чтоб можно было запредиктить что угодно даже то что серверсайднутое молодец UWUKSON1488
 
code_language.lua:
Expand Collapse Copy
local ui = require 'wrapper'
local c_entity = require 'gamesense/entity'

local checkbox = ui.create('animation_fix', 'A'):switch('enable animation fix')

local animation_fix do
    animation_fix = {}

    animation_fix.anim_data = {
        layers = {
            [0] = { cycle = 0, weight = 0 }, -- aim_matrix
            [1] = { cycle = 0, weight = 0 }, -- weapon_action
            [2] = { cycle = 0, weight = 0 }, -- weapon_action_recrouch
            [3] = { cycle = 0, weight = 0 }, -- adjust
            [4] = { cycle = 0, weight = 0 }, -- movement_move
            [5] = { cycle = 0, weight = 0 }, -- movement_strafe
            [6] = { cycle = 0, weight = 0 }, -- movement_strafechange
            [7] = { cycle = 0, weight = 0 }, -- whole_body
            [8] = { cycle = 0, weight = 0 }, -- flashed
            [9] = { cycle = 0, weight = 0 }, -- flinch
            [10] = { cycle = 0, weight = 0 }, -- aliveloop
            [11] = { cycle = 0, weight = 0 }, -- jump
            [12] = { cycle = 0, weight = 0 }, -- land
            [13] = { cycle = 0, weight = 0 }, -- move_blend_walk
            [14] = { cycle = 0, weight = 0 }, -- move_blend_run
            [15] = { cycle = 0, weight = 0 }, -- move_blend_crouch
        },
        server_anim_states = {},
        last_sim_time = 0,
        last_velocity = 0,
        last_duck_amount = 0,
        last_weapon = nil,
    }

    local function lerp(a, b, t)
        return a + (b - a) * t
    end

    animation_fix.setup_command = function(cmd)
        if not checkbox:get() then
            return
        end

        local me = entity.get_local_player()
        if not me then
            return
        end

        local self_index = c_entity.new(me)
        local anim_state = self_index:get_anim_state()
        if not anim_state then return end

        local sim_time = globals.servertickcount()
        local vel_x, vel_y = entity.get_prop(me, "m_vecVelocity")
        local velocity = math.sqrt(vel_x * vel_x + vel_y * vel_y)
        local duck_amount = entity.get_prop(me, "m_flDuckAmount")
        local ducking = entity.get_prop(me, "m_bDucking") == 1
        local on_ground = bit.band(entity.get_prop(me, "m_fFlags"), 1) == 1
        local current_weapon = entity.get_player_weapon(me)

        if velocity < 0.1 then
            velocity = 0
        end

        local server_state = {
            time = sim_time,
            layers = {},
            velocity = velocity,
            duck_amount = duck_amount,
            ducking = ducking,
            on_ground = on_ground,
            weapon = current_weapon,
        }

        for layer_idx, _ in pairs(animation_fix.anim_data.layers) do
            local layer = self_index:get_anim_overlay(layer_idx)
            if layer then
                server_state.layers[layer_idx] = {
                    cycle = layer.cycle,
                    weight = layer.weight,
                }
            end
        end

        table.insert(animation_fix.anim_data.server_anim_states, server_state)

        if #animation_fix.anim_data.server_anim_states > 60 then
            table.remove(animation_fix.anim_data.server_anim_states, 1)
        end
    end

    animation_fix.pre_render = function()
        if not checkbox:get() then
            return
        end

        local me = entity.get_local_player()
        if not me then
            return
        end

        local self_index = c_entity.new(me)
        local anim_state = self_index:get_anim_state()
        if not anim_state then return end

        local current_time = globals.realtime()
        local server_states = animation_fix.anim_data.server_anim_states

        if #server_states < 2 then
            return
        end

        local state1, state2
        for i = #server_states - 1, 1, -1 do
            if server_states[i].time <= current_time and server_states[i+1].time >= current_time then
                state1 = server_states[i]
                state2 = server_states[i+1]
                break
            end
        end

        if not state1 or not state2 then
            state1 = server_states[#server_states - 1]
            state2 = server_states[#server_states]
        end

        local t = (current_time - state1.time) / (state2.time - state1.time)
        t = math.min(1, math.max(0, t))

        for layer_idx, _ in pairs(animation_fix.anim_data.layers) do
            local layer = self_index:get_anim_overlay(layer_idx)
            if layer and state1.layers[layer_idx] and state2.layers[layer_idx] then
                local cycle1 = state1.layers[layer_idx].cycle
                local cycle2 = state2.layers[layer_idx].cycle
                local weight1 = state1.layers[layer_idx].weight
                local weight2 = state2.layers[layer_idx].weight

                if (layer_idx == 1 or layer_idx == 2) and state1.weapon ~= state2.weapon then
                    layer.cycle = cycle2
                    layer.weight = weight2
                else
                    layer.cycle = lerp(cycle1, cycle2, t)
                    layer.weight = lerp(weight1, weight2, t)
                end
            end
        end

        local velocity = lerp(state1.velocity, state2.velocity, t)
        local duck_amount = lerp(state1.duck_amount, state2.duck_amount, t)
        local ducking = state1.ducking
        local on_ground = state1.on_ground
        local current_weapon = state1.weapon

        animation_fix.anim_data.last_velocity = velocity
        animation_fix.anim_data.last_duck_amount = duck_amount
        animation_fix.anim_data.last_weapon = current_weapon
    end
end

client.set_event_callback('pre_render', function()
    animation_fix.pre_render()
end)

client.set_event_callback('setup_command', function(cmd)
    animation_fix.setup_command(cmd)
end)

вот ссылка на библиотеку wrapper: https://yougame.biz/threads/339089/
легенда, пойду перепащу в свой mr. script
 
улучшил читабельность кода для ребят, на будущее, умоляю прекрати делать миллиард таблиц
(убрал интерполяцию на фейклаги, выглядит будто updateCSA не работает там)

Код:
Expand Collapse Copy
local с_ui = require 'wrapper'
local c_entity = require 'gamesense/entity'
local vector = require 'vector'
local inspect = require 'gamesense/inspect'

local checkbox = с_ui.create('animation_fix', 'A'):switch('enable animation fix')

local interpolate do
    local doubletap = {ui.reference("RAGE", "Aimbot", "Double tap")}
    local onshot = {ui.reference("AA", "Other", "On shot anti-aim")}

    local LAYERS_LIMIT = 15
    local data = {}; do
        data.layers = { }

        for i = 1, LAYERS_LIMIT do
            data.layers[i] = {
                cycle = 0,
                weight = 0
            }
        end

        data.server = {}
        data.sim_time = 0
        data.velocity = 0
        data.duck_amount = 0
        data.weapon = 0
    end

    local function lerp(a, b, c)
        return a + (b - a) * c
    end

    local function get_anim_state(player)
        local index = c_entity(player)
        local animstate = c_entity.get_anim_state(index)

        return animstate
    end

    local function get_anim_overlay(player, num)
        local index = c_entity(player)
        local layer = c_entity.get_anim_overlay(index, num)
            
        return layer
    end

    local function on_setup_command(cmd)
        if not checkbox:get() then
            return
        end
        
        local me = entity.get_local_player()

        if me == nil or not entity.is_alive(me) then
            return
        end
        
        local animstate = get_anim_state(me)

        if animstate == nil then
            return
        end

        local server_tickcount = globals.servertickcount()
        local velocity = vector(entity.get_prop(me, "m_vecVelocity"))

        local speed = velocity:length2d()
        speed = speed < 0.1 and 0 or speed

        local duck_amount = entity.get_prop(me, "m_flDuckAmount")
        local is_ducking = entity.get_prop(me, "m_bDucking") > 0

        local on_ground = bit.band(entity.get_prop(me, "m_fFlags"), 1) == 1
        local weapon = entity.get_player_weapon(me)

        local server_state = {
            time = server_tickcount,
            layers = {},
            velocity = speed,
            duck_amount = duck_amount,
            ducking = is_ducking,
            on_ground = on_ground,
            weapon = weapon
        }

        for idx, info in ipairs(data.layers) do
            local layer = get_anim_overlay(me, idx)
            if layer ~= nil then
                server_state.layers[idx] = {
                    cycle = layer.cycle,
                    weight = layer.weight
                }
            end

            table.insert(data.server, server_state)

            if #data.server >= 64 then -- to test, replace to > 60
                table.remove(data.server, 1)
            end
        end
    end

    local function on_pre_render()
        if not checkbox:get() then
            return
        end
        
        local me = entity.get_local_player()

        if me == nil or not entity.is_alive(me) then
            return
        end

        local animstate = get_anim_state(me)

        if animstate == nil then
            return
        end

        local realtime = globals.realtime()
        local server_data = data.server

        if #server_data < 2 then
            return
        end

        if not (ui.get(doubletap[1]) and ui.get(doubletap[2])) or (ui.get(onshot[1]) and ui.get(onshot[2])) then
            goto continue
        end

        local jmp, jmp1

        for i = #server_data - 1, 1, -1 do
            local ctx = server_data[i]

            if ctx == nil then
                goto continue
            end

            if ctx.time <= realtime and server_data[i + 1] >= realtime then
                jmp = ctx
                jmp1 = server_data[i + 1]
                break
            end

            if not jmp or not jmp1 then
                jmp = server_data[#server_data - 1]
                jmp1 = ctx
            end

            ::continue::
        end

        local time = (realtime - jmp.time) / (jmp1.time - jmp.time)
        time = math.min(1, math.max(0, time))

        for idx, info in ipairs(data.layers) do
            local layer = get_anim_overlay(me, idx)

            if layer ~= nil and jmp.layers[idx] ~= nil and jmp1.layers[idx] ~= nil then
                local current_data = {
                    cycle = {
                        [1] = jmp.layers[idx].cycle,
                        [2] = jmp1.layers[idx].cycle
                    },
                    weight = {
                        [1] = jmp.layers[idx].weight,
                        [2] = jmp1.layers[idx].weight
                    }
                }

                if idx == 1 or idx == 2 and jmp.weapon ~= jmp1.weapon then
                    layer.cycle = current_data.cycle[2]
                    layer.weight = current_data.weight[2]
                else
                    layer.cycle = lerp(current_data.cycle[1], current_data.cycle[2], time)
                    layer.weight = lerp(current_data.weight[1], current_data.weight[2], time)
                end
            end
        end

        local current_velocity = lerp(jmp.velocity, jmp1.velocity, time)

        local duck_amount = lerp(jmp.duck_amount, jmp1.duck_amount, time)
        local ducking = jmp.ducking
        local on_ground = jmp.on_ground
        local current_weapon = jmp.weapon

        data.velocity = velocity
        data.duck_amount = duck_amount
        data.weapon = current_weapon

        ::continue::
    end

    client.set_event_callback("setup_command", on_setup_command)
    client.set_event_callback("pre_render", on_pre_render)
end
 
обновил скрипт

из основного:
C++:
Expand Collapse Copy
исправил количество 'слоёв анимации' (почему у меня в прошлом коде было их 15, когда в CS:GO поддерживается только 13 (от 0 до 12, вроде как...) - я не знаю. делал всё на скорую руку, поэтому там очень много приколов... [ уже просто было =) ])
полностью переписал весь скрипт, чтобы людям было куда приятней смотреть, ну и разбирать его
добавил 'полную очистку' памяти при выгрузке скрипта (теперь все данные выгружаются, предотвращая утечки памяти [ ну и теперь пишет какое кол-во памяти очистилось ] )

Пожалуйста, авторизуйтесь для просмотра ссылки.
 
Назад
Сверху Снизу