привет форум
в попытке реализовать в аи пик логику стрелять толькко в бектрек но я не могу понять причину не срабатывания?
Код:
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)
в попытке реализовать в аи пик логику стрелять толькко в бектрек но я не могу понять причину не срабатывания?