Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Вопрос Попытка shot at backtrack

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
6 Дек 2021
Сообщения
59
Реакции
4
привет форум
Код:
Expand Collapse Copy
local flow_in     = 1
local anim_layers = 15
local pose_params = 24
local rec_life    = 0.5
local fl_ground   = 1

local ui_fake_lat = ui.find("Miscellaneous", "Main", "Other", "Fake Latency")
local bt_font     = render.load_font('Verdana', 11, 'ab')

local hb = { head=0, chest=5, stomach=3, neck=8, lthigh=7, rthigh=8, lcalf=9, rcalf=10 }
local hb_armor = {
    [hb.head]=1,    [hb.chest]=2,   [hb.stomach]=3,
    [hb.neck]=8,
    [hb.lthigh]=6,  [hb.rthigh]=7,  [hb.lcalf]=6,  [hb.rcalf]=7,
}

local edges = {
    {1,2},{2,3},{3,4},{4,1},
    {5,6},{6,7},{7,8},{8,5},
    {1,5},{2,6},{3,7},{4,8}
}

local ctx = new_class()

    :struct 'net' {
        interp = function(self)
            local interp = cvar.cl_interp:float()
            local ratio  = cvar.cl_interp_ratio:float()
            local uprate = cvar.cl_updaterate:float()
            local ok1, mn = pcall(function() return cvar.sv_client_min_interp_ratio:float() end)
            local ok2, mx = pcall(function() return cvar.sv_client_max_interp_ratio:float() end)
            if ok1 and mn then ratio = math.max(ratio, mn) end
            if ok2 and mx then ratio = math.min(ratio, mx) end
            return math.max(interp, ratio / uprate)
        end,

        latency = function(self)
            local ch = utils.net_channel()
            if not ch then return 0 end
            return math.max(0, ch.avg_latency[flow_in])
        end,

        lag_push = function(self)
            local ok, v = pcall(function() return cvar.sv_lagpushticks:float() end)
            return (ok and v) and v or 0
        end,

        max_unlag = function(self)
            local ok, v = pcall(function() return cvar.sv_maxunlag:float() end)
            return (ok and v and v > 0) and v or 0.2
        end,

        target_time = function(self)
            return (self.state.cmd_tick + self:lag_push()) * globals.tickinterval - self:interp()
        end,
    }

    :struct 'storage' {
        data = {},

        store = function(self, player)
            if not player:is_alive() or player:is_dormant() then
                self.data[player:get_index()] = nil
                return
            end

            local nstate = player:get_network_state()
            if nstate > 1 then return end

            local sim = player:get_simulation_time()
            if not sim or sim.current <= 0 then return end
            if sim.current == sim.old then return end

            local stime = sim.current
            local tick  = to_ticks(stime)
            local idx   = player:get_index()

            if not self.data[idx] then self.data[idx] = {} end
            local recs = self.data[idx]

            if #recs > 0 and recs[1].tick == tick then return end

            if #recs > 0 then
                local d = stime - recs[1].sim_time
                if d < 0 or d > globals.tickinterval * 4 then
                    self.data[idx] = {}
                    recs = self.data[idx]
                end
            end

            local layers = {}
            for i = 0, anim_layers - 1 do
                local l = player:get_anim_overlay(i)
                if l then
                    layers[i] = { sequence=l.sequence, cycle=l.cycle, weight=l.weight, playback_rate=l.playback_rate, order=l.order }
                end
            end

            local pose = {}
            for i = 0, pose_params - 1 do
                pose[i] = player.m_flPoseParameter[i] or 0
            end

            local bones = {}
            for i = 0, 64 do
                local b = player:get_bone_position(i)
                if b then bones[i] = b end
            end

            table.insert(recs, 1, {
                tick=tick, sim_time=stime, old_sim=sim.old,
                origin=player:get_origin(), velocity=player.m_vecVelocity,
                flags=player.m_fFlags, duck=player.m_flDuckAmount or 0,
                angles=player.m_angEyeAngles, sequence=player.m_nSequence,
                cycle=player.m_flCycle, pose=pose, layers=layers, bones=bones, nstate=nstate,
            })

            local now = globals.curtime
            while #recs > 0 and (now - recs[#recs].sim_time) > rec_life do
                recs[#recs] = nil
            end
        end,

        clear = function(self)
            self.data = {}
        end,
    }

    :struct 'bt' {
        rec_valid = function(self, r)
            if not r.sim_time or r.sim_time <= 0 then return false end
            if r.old_sim and r.old_sim == r.sim_time then return false end
            local o = r.origin
            if not o or (o.x == 0 and o.y == 0 and o.z == 0) then return false end
            if r.flags == nil then return false end
            return true
        end,

        chain_gap = function(self, recs, idx)
            local a = recs[idx]
            local b = recs[idx + 1]
            if not b then return false end
            local d = a.sim_time - b.sim_time
            return d < 0 or d > globals.tickinterval * 4
        end,

        lerp_vec = function(self, a, b, t)
            return vector(a.x+(b.x-a.x)*t, a.y+(b.y-a.y)*t, a.z+(b.z-a.z)*t)
        end,

        lerp_recs = function(self, prev, curr, tt)
            local dt = curr.sim_time - prev.sim_time
            if dt <= 0 then return curr end
            local t = math.max(0, math.min(1, (tt - prev.sim_time) / dt))

            local pose = {}
            for i = 0, pose_params - 1 do
                pose[i] = (prev.pose[i] or 0) + ((curr.pose[i] or 0) - (prev.pose[i] or 0)) * t
            end

            local layers = {}
            for i = 0, anim_layers - 1 do
                local pl, cl = prev.layers[i], curr.layers[i]
                if pl and cl then
                    layers[i] = { sequence=cl.sequence, cycle=pl.cycle+(cl.cycle-pl.cycle)*t, weight=pl.weight+(cl.weight-pl.weight)*t, playback_rate=cl.playback_rate, order=cl.order }
                elseif cl then layers[i] = cl end
            end

            return {
                tick=curr.tick, sim_time=tt,
                origin=self:lerp_vec(prev.origin, curr.origin, t),
                velocity=prev.velocity, flags=curr.flags,
                duck=prev.duck+(curr.duck-prev.duck)*t,
                angles=curr.angles, sequence=curr.sequence,
                cycle=prev.cycle+(curr.cycle-prev.cycle)*t,
                pose=pose, layers=layers, bones=curr.bones, lerped=true,
            }
        end,

        render_rec = function(self, idx, tt)
            local recs = self.storage.data[idx]
            if not recs or #recs == 0 then return nil end
            local mu   = self.net:max_unlag()
            local prev = nil
            for i = 1, #recs do
                local r = recs[i]
                if r.sim_time < tt - mu then break end
                if self:rec_valid(r) and not self:chain_gap(recs, i) then
                    if prev and r.sim_time <= tt and prev.sim_time >= tt then
                        return self:lerp_recs(r, prev, tt)
                    end
                    prev = r
                end
            end
            return prev
        end,

        shoot_rec = function(self, idx)
            local recs = self.storage.data[idx]
            if not recs or #recs == 0 then return nil end

            local now      = globals.curtime
            local mu       = self.net:max_unlag()
            local min_tks  = self.ui_cfg.bt_minticks:get()
            local lat      = self.net:latency()
            local interp   = self.net:interp()
            local min_age  = lat + interp
            local best     = nil

            for i = 1, #recs do
                local r   = recs[i]
                local age = now - r.sim_time
                if age > mu then break end

                local tks = to_ticks(age)
                if tks >= min_tks
                and age > min_age
                and self:rec_valid(r)
                and not self:chain_gap(recs, i)
                and (not r.nstate or r.nstate <= 1)
                then
                    best = r
                end
            end

            if best then
                local age = now - best.sim_time
                return best, age, to_ticks(age)
            end
        end,

        fake_lat = function(self, age)
            local lat    = self.net:latency()
            local interp = self.net:interp()
            local need   = age - lat - interp
            return math.floor(math.max(0, math.min(100, need * 1000)))
        end,
    }

    :struct 'state' {
        cmd_tick = 0,
        dbg_t    = 0,
        rate_tmr = 0,
        peek     = nil,
        ret_pos  = nil,
        orig_fl  = 0,

        reset = function(self)
            self.peek     = nil
            self.rate_tmr = 0
            self.ret_pos  = nil
            if ui_fake_lat then ui_fake_lat:set(self.orig_fl) end
            self.orig_fl  = 0
        end,
    }

    :struct 'ui_cfg' {
        init = function(self)
            ui.sidebar("Dormant", "crosshairs")

            local g_main = ui.create("Dormant", "general")
            local g_move = ui.create("Dormant", "movement")
            local g_aim  = ui.create("Dormant", "targeting")
            local g_bt   = ui.create("Dormant", "backtrack")
            local g_vis  = ui.create("Dormant", "visuals")
            local g_dbg  = ui.create("Dormant", "debug")

            self.enabled = g_main:switch("enabled")
            self.enabled:color_picker(color(110, 90, 255, 255))
            self.weapons = g_main:selectable("weapons", {"SSG-08", "Deagle", "Pistols"})
            self.weapons:tooltip("peek activates only for selected weapons")

            self.simtime  = g_move:slider("sim time",    25, 35, 28, 0.01, "s")
            self.ratelim  = g_move:slider("rate limit",   0, 30,  2, 0.01, "s")
            self.ret_dist = g_move:slider("retreat dist", 10, 60, 25, nil, function(v) return v .. " u" end)
            self.steps    = g_move:slider("sim steps",   10, 40, 20, nil, function(v) return v .. " t" end)
            self.simtime:tooltip("how long the peek lasts before retreating")
            self.ratelim:tooltip("scan frequency — 0 means every frame")
            self.ret_dist:tooltip("how far to retreat after peek")
            self.steps:tooltip("simulation depth per direction")

            self.hitboxes = g_aim:listable("hitboxes", {"Head", "Chest", "Stomach", "Legs"})
            self.mindmg   = g_aim:slider("min damage", 1, 120, 30, nil, function(v) return v .. " hp" end)
            self.hchance  = g_aim:slider("hit chance", 0, 100, 35, nil, function(v) return v == 0 and "default" or v .. "%" end)
            self.unsafe   = g_aim:switch("unsafety")
            self.hitboxes:tooltip("hitboxes scanned to find a valid peek position")
            self.mindmg:tooltip("minimum required damage for peek to trigger")
            self.hchance:tooltip("0 = use ragebot default")
            self.unsafe:tooltip("disables safe points, body aim and hitbox safety")

            do
                local saved = {1, 2, 3, 4}
                self.hitboxes:set(saved)
                self.hitboxes:set_callback(function()
                    local cur = self.hitboxes:get()
                    if #cur > 0 then saved = cur else self.hitboxes:set(saved) end
                end)
            end

            self.bt_on       = g_bt:switch("bt shoot")
            self.bt_minticks = g_bt:slider("min ticks", 1, 20, 6, nil, function(v)
                return string.format("%d t  (~%d ms)", v, math.floor(v * globals.tickinterval * 1000))
            end)
            self.bt_tol = g_bt:slider("tolerance", 50, 200, 100, nil, function(v) return v .. " ms" end)
            self.bt_on:tooltip("uses fake latency to shoot at an older backtrack record")
            self.bt_minticks:tooltip("minimum record age — server window is 100 ms")
            self.bt_tol:tooltip("max delta between our target_time and the record")

            self.bt_on:set_callback(function(s)
                local v = s:get()
                self.bt_minticks:visibility(v)
                self.bt_tol:visibility(v)
            end, true)

            self.show_bt    = g_vis:switch("backtrack box")
            self.col_btbox  = self.show_bt:color_picker(color(220, 60, 60, 220))
            self.show_lerp  = g_vis:switch("lerp box")
            self.col_lerped = self.show_lerp:color_picker(color(80, 200, 100, 180))
            self.show_norm  = g_vis:switch("normal box")
            self.col_box    = self.show_norm:color_picker(color(47, 117, 221, 200))
            self.show_ticks = g_vis:switch("tick counter")
            self.col_text   = self.show_ticks:color_picker(color(255, 255, 255, 255))
            self.show_bt:tooltip("red box — exact record the script shoots at")
            self.show_lerp:tooltip("green box — interpolated render position")
            self.show_norm:tooltip("blue box — current backtrack render box")
            self.show_ticks:tooltip("tick age label above players")

            self.debug     = g_dbg:switch("debug log")
            self.dbg_stats = g_dbg:label("waiting...")
            self.debug:tooltip("shows live bt network stats")

            self.debug:set_callback(function(s)
                self.dbg_stats:visibility(s:get())
            end, true)

            local all = {
                self.weapons,
                self.simtime, self.ratelim, self.ret_dist, self.steps,
                self.hitboxes, self.mindmg, self.hchance, self.unsafe,
                self.bt_on,
                self.show_bt, self.show_lerp, self.show_norm, self.show_ticks,
                self.debug,
            }

            self.enabled:set_callback(function(s)
                local v = s:get()
                for _, item in ipairs(all) do item:visibility(v) end
                if not v then
                    self.bt_minticks:visibility(false)
                    self.bt_tol:visibility(false)
                    self.dbg_stats:visibility(false)
                else
                    self.bt_minticks:visibility(self.bt_on:get())
                    self.bt_tol:visibility(self.bt_on:get())
                    self.dbg_stats:visibility(self.debug:get())
                end
            end, true)

            self.wcfg = {}
            for _, name in ipairs({"SSG-08", "Desert Eagle", "Pistols"}) do
                local ok, res = pcall(function()
                    return {
                        sel = {
                            hscale  = ui.find("Aimbot","Ragebot","Selection",name,"Multipoint","Head Scale"),
                            bscale  = ui.find("Aimbot","Ragebot","Selection",name,"Multipoint","Body Scale"),
                            hchance = ui.find("Aimbot","Ragebot","Selection",name,"Hit Chance"),
                        },
                        saf = {
                            bodyaim  = ui.find("Aimbot","Ragebot","Safety",name,"Body Aim"),
                            spoints  = ui.find("Aimbot","Ragebot","Safety",name,"Safe Points"),
                            ehsafety = ui.find("Aimbot","Ragebot","Safety",name,"Ensure Hitbox Safety"),
                        }
                    }
                end)
                if ok then self.wcfg[name] = res end
            end

            self.pa_ok, self.pa = pcall(function()
                return {
                    ui.find("Aimbot","Ragebot","Main","Peek Assist"),
                    { ui.find("Aimbot","Ragebot","Main","Peek Assist","Style") },
                    ui.find("Aimbot","Ragebot","Main","Peek Assist","Auto Stop"),
                    ui.find("Aimbot","Ragebot","Main","Peek Assist","Retreat Mode"),
                }
            end)

            self.dtap = ui.find("Aimbot","Ragebot","Main","Double Tap")
        end,

        scan_hb = function(self)
            local r = {}
            if self.hitboxes:get("Head")    then table.insert(r, hb.head) end
            if self.hitboxes:get("Chest")   then table.insert(r, hb.chest) end
            if self.hitboxes:get("Stomach") then table.insert(r, hb.stomach) end
            if self.hitboxes:get("Legs") then
                table.insert(r, hb.lthigh); table.insert(r, hb.rthigh)
                table.insert(r, hb.lcalf);  table.insert(r, hb.rcalf)
            end
            return r
        end,

        ov_reset = function(self)
            pcall(function() self.dtap:override() end)
            if self.pa_ok then pcall(function() self.pa[4]:override() end) end
            for _, c in pairs(self.wcfg) do
                pcall(function()
                    c.sel.hscale:override(); c.sel.bscale:override(); c.sel.hchance:override()
                    c.saf.bodyaim:override(); c.saf.spoints:override(); c.saf.ehsafety:override()
                end)
            end
        end,

        ov_peek = function(self)
            local hc     = self.hchance:get()
            local unsafe = self.unsafe:get()
            if self.pa_ok then pcall(function() self.pa[4]:override("On Shot") end) end
            for _, c in pairs(self.wcfg) do
                pcall(function()
                    c.sel.hscale:override(100); c.sel.bscale:override(100)
                    if hc ~= 0 then c.sel.hchance:override(hc) end
                    if unsafe then
                        c.saf.bodyaim:override("Default")
                        c.saf.spoints:override("Default")
                        c.saf.ehsafety:override({})
                    end
                end)
            end
        end,
    }

    :struct 'damage' {
        arm_mult = function(self,t)
        if t == 1 then return 4.0
            elseif t == 3 then return 1.25
            elseif t == 4 or t == 5 then return 0.75
            elseif t == 6 or t == 7 then return 0.75
            elseif t == 8 then return 1.5
            else return 1.0 end
        end,

        calc = function(self, from, to, tgt, atype, wi)
            local dist     = (to - from):length()
            local range    = wi.range          or 8192
            local rm       = wi.range_modifier or 0.99
            local base_dmg = wi.damage         or 0
            local ar       = wi.armor_ratio    or 0.5

            local dmg = base_dmg * math.pow(rm, math.min(range, dist) * 0.002)

            dmg = dmg * self:arm_mult(atype)

            if tgt.m_ArmorValue > 0 then
                local armor_bonus  = ar * 0.5
                local armor_damage = dmg * ar

                if atype == 1 and tgt.m_bHasHelmet then
                    armor_damage = armor_damage * 0.5
                    dmg = dmg * 0.5
                end

                if armor_damage > tgt.m_ArmorValue then
                    local scale = tgt.m_ArmorValue / armor_damage
                    dmg = dmg * (1.0 - armor_bonus * scale)
                else
                    dmg = dmg * (1.0 - armor_bonus)
                end
            end

            return dmg
        end,

        hittable = function(self, hbs, me, weap, tgt, mdmg)
            local res = {}
            local eye = me:get_eye_position()
            local wi  = weap:get_weapon_info()
            local hp  = tgt.m_iHealth
            for i = 1, #hbs do
                local h   = hbs[i]
                local pos = tgt:get_hitbox_position(h)
                if pos then
                    local dmg = self:calc(eye, pos, tgt, hb_armor[h] or 0, wi)
                    if not (dmg < mdmg) or not (dmg < hp) then
                        table.insert(res, { index=h, pos=pos })
                    end
                end
            end
            return res
        end,
    }

    :struct 'peek' {
        trace = function(self, me, from, to)
            return utils.trace_bullet(me, from, to, function(e)
                return e ~= me and e:is_enemy()
            end)
        end,

        can_hit = function(self, me, tgt, eye, htbl, mdmg)
            local hp = tgt.m_iHealth
            for i = 1, #htbl do
                local dmg = self:trace(me, eye, htbl[i].pos)
                if dmg and (mdmg <= dmg or hp <= dmg) then return true end
            end
            return false
        end,

        sim_check = function(self, sim, me, tgt, htbl, mdmg)
            local eye = sim.origin + vector(0, 0, sim.view_offset)
            return sim, self:can_hit(me, tgt, eye, htbl, mdmg)
        end,

        sim_step = function(self, cmd, me, tgt, sim, yaw, htbl, mdmg)
            cmd.view_angles.y = yaw
            sim:think(1)
            if bit.band(sim.flags, fl_ground) == 0 then return nil, false end
            local _, hit = self:sim_check(sim, me, tgt, htbl, mdmg)
            if hit then sim:think(1) end
            return sim, hit
        end,

        move_to = function(self, cmd, me, dest)
            local d     = dest - me:get_origin()
            local dist2 = d:length2dsqr()
            if dist2 < 25 then
                local vel = me.m_vecVelocity
                cmd.move_yaw=vel:angles().y; cmd.forwardmove=-vel:length(); cmd.sidemove=0
                return true
            else
                cmd.move_yaw=d:angles().y; cmd.forwardmove=450; cmd.sidemove=0
                return false
            end
        end,

        clear_input = function(self, cmd)
            cmd.in_duck=false; cmd.in_jump=false; cmd.in_speed=false
            cmd.in_forward=true; cmd.in_back=false
            cmd.in_moveleft=false; cmd.in_moveright=false
        end,

        weap_key = function(self, weap, wi)
            local idx   = weap:get_weapon_index()
            local wtype = wi.weapon_type
            if idx == 1 or idx == 64 then return "Deagle"
            elseif idx == 40 then return "SSG-08"
            elseif wtype == 1 then return "Pistols"
            else return nil end
        end,

        can_fire = function(self, me, weap, wi)
            if not me or not weap then return false end
            if wi.max_clip1 == 0 or weap.m_iClip1 == 0 then return false end
            if globals.curtime < me.m_flNextAttack then return false end
            if globals.curtime < weap.m_flNextPrimaryAttack then return false end
            return true
        end,

        ent_ok = function(self, e)
            if not e then return false end
            local ok, r = pcall(function() return e[0] end)
            return ok and r ~= nil
        end,

        find = function(self, cmd, me, weap)
            local ft   = globals.frametime
            local ucf  = self.ui_cfg
            local mdmg = ucf.mindmg:get()
            local hbs  = ucf:scan_hb()
            local s    = self.state

            if s.peek and self:ent_ok(s.peek.tgt) then
                local hp = s.peek.tgt.m_iHealth
                if mdmg >= 100 then mdmg = mdmg + hp - 100 end
                local htbl   = self.damage:hittable(hbs, me, weap, s.peek.tgt, mdmg)
                local _, hit = self:sim_check(s.peek.ctx, me, s.peek.tgt, htbl, mdmg)
                if hit then s.peek.stime = 0 end
                s.peek.stime = s.peek.stime + ft
                return true
            end

            local rate = ucf.ratelim:get() * 0.01
            if rate > 0 then
                if s.rate_tmr > 0 then s.rate_tmr = s.rate_tmr - ft; return false
                else s.rate_tmr = rate end
            end

            if cmd.in_forward or cmd.in_back or cmd.in_moveleft or cmd.in_moveright then return false end
            if bit.band(me.m_fFlags, fl_ground) == 0 then return false end
            if me.m_vecVelocity:length2dsqr() > 6400 then return false end

            local tgt = entity.get_threat()
            if not tgt or tgt:is_dormant() then return false end

            local hp = tgt.m_iHealth
            if mdmg >= 100 then mdmg = mdmg + hp - 100 end

            local htbl = self.damage:hittable(hbs, me, weap, tgt, mdmg)
            if self:can_hit(me, tgt, me:get_eye_position(), htbl, mdmg) then return false end

            local mypos = me:get_origin()
            local toeny = (tgt:get_origin() - mypos):angles().y + 180
            local yaw_l = toeny - 90
            local yaw_r = toeny + 90

            local oy    = cmd.view_angles:clone()
            local ofwd, oside, oduck, ojump, ospd =
                cmd.forwardmove, cmd.sidemove, cmd.in_duck, cmd.in_jump, cmd.in_speed

            cmd.forwardmove=450; cmd.sidemove=0
            cmd.in_duck=false; cmd.in_jump=false; cmd.in_speed=false

            local sl = me:simulate_movement(nil, vector(), 1)
            local sr = me:simulate_movement(nil, vector(), 1)
            local dl, dr = false, false

            for i = 1, ucf.steps:get() do
                if not dl then
                    local sm, hit = self:sim_step(cmd, me, tgt, sl, yaw_l, htbl, mdmg)
                    if not sm then dl = true
                    elseif hit then s.peek = { ctx=sm, tgt=tgt, stime=0, retreat=-1 }; break end
                end
                if not dr then
                    local sm, hit = self:sim_step(cmd, me, tgt, sr, yaw_r, htbl, mdmg)
                    if not sm then dr = true
                    elseif hit then s.peek = { ctx=sm, tgt=tgt, stime=0, retreat=-1 }; break end
                end
            end

            cmd.view_angles.y=oy.y; cmd.forwardmove=ofwd; cmd.sidemove=oside
            cmd.in_duck=oduck; cmd.in_jump=ojump; cmd.in_speed=ospd

            return s.peek ~= nil
        end,

        run = function(self, cmd, me, weap, wi)
            local fready = self:can_fire(me, weap, wi)
            local found  = self:find(cmd, me, weap)
            local s      = self.state
            local ucf    = self.ui_cfg

            if not s.peek then return end

            local stime = s.peek.stime or 0
            if (ucf.simtime:get() * 0.01) < stime then found = false end
            if wi.weapon_type == 5 and not me.m_bIsScoped then found = false end

            if (s.peek.retreat or -1) <= 0 and found then
                local pctx = s.peek.ctx
                if not pctx or not pctx.origin then
                    s:reset()
                    ucf:ov_reset()
                    return
                end

                if not s.ret_pos then
                    local mypos = me:get_origin()
                    local dir   = pctx.origin - mypos
                    dir:normalize()
                    local back    = pctx.origin - dir * ucf.ret_dist:get()
                    local mins    = pctx.obb_mins or vector(-16, -16, 0)
                    local maxs    = pctx.obb_maxs or vector(16, 16, 72)
                    local tr      = utils.trace_hull(mypos, back, mins, maxs, me, 33636363, 0)
                    s.ret_pos     = tr and tr.end_pos or mypos
                end

                if ucf.bt_on:get() and s.peek.tgt then
                    local tidx              = s.peek.tgt:get_index()
                    local brec, bage, btks = self.bt:shoot_rec(tidx)

                    if brec and btks >= ucf.bt_minticks:get() then
                        local fl = self.bt:fake_lat(bage)
                        if s.orig_fl == 0 and ui_fake_lat then s.orig_fl = ui_fake_lat:get() end
                        if ui_fake_lat then ui_fake_lat:set(fl) end
                    else
                        cmd.in_attack = false
                    end
                end

                local arrived = self:move_to(cmd, me, pctx.origin)
                self:clear_input(cmd)
                ucf:ov_peek()
                s.peek.retreat = 0
                if arrived then s.peek.retreat = 1 end

            elseif not fready then
                s:reset()

            elseif not s.peek.ctx or (s.peek.retreat or -1) == -1 then
                return

            else
                s.peek.retreat = (s.peek.retreat or 0) + 1

                if ui_fake_lat then ui_fake_lat:set(s.orig_fl) end
                s.orig_fl = 0

                local dest    = s.ret_pos or me:get_origin()
                local arrived = self:move_to(cmd, me, dest)
                local vel     = me.m_vecVelocity
                local adiff   = (dest - me:get_origin()):angles() - vel:angles()

                self:clear_input(cmd)
                ucf:ov_peek()

                if vel:length2dsqr() > 1600 and math.abs(adiff.y) < 20 then
                    pcall(function()
                        rage.exploit:force_teleport()
                        ucf.dtap:override(false)
                    end)
                end

                if fready and arrived then
                    s:reset()
                    ucf:ov_reset()
                end
            end
        end,
    }

    :struct 'viz' {
        box = function(self, origin, col)
            local r, h = 16, 72
            local x, y, z = origin.x, origin.y, origin.z
            local pts = {
                vector(x-r,y-r,z),   vector(x+r,y-r,z),
                vector(x+r,y+r,z),   vector(x-r,y+r,z),
                vector(x-r,y-r,z+h), vector(x+r,y-r,z+h),
                vector(x+r,y+r,z+h), vector(x-r,y+r,z+h),
            }
            local scr = {}
            local vis = 0
            for i = 1, 8 do
                scr[i] = render.world_to_screen(pts[i])
                if scr[i] then vis = vis + 1 end
            end
            if vis == 0 then return end
            for _, e in ipairs(edges) do
                if scr[e[1]] and scr[e[2]] then
                    render.line(scr[e[1]], scr[e[2]], col)
                end
            end
        end,

        draw = function(self)
            if not globals.is_in_game then return end
            local me = entity.get_local_player()
            if not me or not me:is_alive() then return end

            local ucf = self.ui_cfg
            if not ucf.enabled:get() then return end

            local tt = self.net:target_time()
            if tt <= 0 then tt = globals.curtime - self.net:latency() - self.net:interp() end

            entity.get_players(true, false, function(p)
                if not p:is_alive() then return end

                local idx  = p:get_index()
                local recs = self.storage.data[idx]
                if not recs or #recs == 0 then return end

                local rec = self.bt:render_rec(idx, tt)
                if not rec then return end

                if rec.lerped then
                    if ucf.show_lerp:get() then self:box(rec.origin, ucf.col_lerped:get()) end
                else
                    if ucf.show_norm:get() then self:box(rec.origin, ucf.col_box:get()) end
                end

                if ucf.bt_on:get() and ucf.show_bt:get() then
                    local brec, _, btks = self.bt:shoot_rec(idx)
                    if brec and btks >= ucf.bt_minticks:get() then
                        self:box(brec.origin, ucf.col_btbox:get())
                    end
                end

                if not ucf.show_ticks:get() then return end

                local bbox = p:get_bbox()
                if not bbox or not bbox.pos1 or not bbox.pos2 or bbox.alpha <= 0 then return end

                local cx  = (bbox.pos1.x + bbox.pos2.x) / 2
                local ty  = bbox.pos1.y - 16
                local ty2 = bbox.pos1.y - 4
                local tc  = ucf.col_text:get()
                local sh  = color(0, 0, 0, 180)

                local lbl = rec.lerped and 'BT~' or 'BT'
                render.text(bt_font, vector(cx+1,ty+1),  sh, 'c', lbl)
                render.text(bt_font, vector(cx,  ty),    tc, 'c', lbl)

                local ts = string.format('[%dt]', to_ticks(globals.curtime - rec.sim_time))
                render.text(bt_font, vector(cx+1,ty2+1), sh, 'c', ts)
                render.text(bt_font, vector(cx,  ty2),   tc, 'c', ts)
            end)
        end,
    }

ctx.ui_cfg:init()

events.createmove:set(function(cmd)
    ctx.state.cmd_tick = cmd.tickcount
end)

events.net_update_end:set(function()
    if not globals.is_in_game then return end
    local me = entity.get_local_player()
    if not me or not me:is_alive() then return end

    entity.get_players(true, false, function(p)
        ctx.storage:store(p)
    end)

    if not ctx.ui_cfg.debug:get() then return end
    local now = globals.curtime
    if now - ctx.state.dbg_t > 3 then
        ctx.state.dbg_t = now
        local total = 0
        for _, r in pairs(ctx.storage.data) do total = total + #r end
        ctx.ui_cfg.dbg_stats:name(string.format(
            "lat %dms  interp %dms  stored %d  push %d",
            math.floor(ctx.net:latency() * 1000),
            math.floor(ctx.net:interp() * 1000),
            total,
            ctx.net:lag_push()
        ))
    end
end)

local function cm_peek(cmd)
    local ucf = ctx.ui_cfg
    if not ucf.enabled:get() then ctx.state:reset(); ucf:ov_reset(); return end
    local me   = entity.get_local_player()
    if not me then return end
    local weap = me:get_player_weapon()
    if not weap then return end
    local wi   = weap:get_weapon_info()
    if not wi then return end
    local wk   = ctx.peek:weap_key(weap, wi)
    if not wk or not ucf.weapons:get(wk) then
        ctx.state:reset(); ucf:ov_reset(); return
    end
    ctx.peek:run(cmd, me, weap, wi)
end

ctx.ui_cfg.enabled:set_callback(function(self)
    local en = self:get()
    if not en then ctx.state:reset(); ctx.ui_cfg:ov_reset() end
    events.aim_fire(function()
        if not ctx.state.peek then return nil end
        ctx.state:reset()
    end, en)
    events.createmove(cm_peek, en)
end, true)

events.render:set(function() ctx.viz:draw() end)

events.level_init:set(function()
    ctx.storage:clear()
    ctx.state:reset()
end)

в попытке реализовать в аи пик логику стрелять толькко в бектрек но я не могу понять причину не срабатывания?
 
Назад
Сверху Снизу