-- =====================================================================
-- Anti-Aim + Resolver Script for Neverlose
-- Organized into TABS (sections) with features pulled from both
-- working community scripts (hysteria + wraith).
--
-- Uses the VERIFIED API: ui.find(...) references + :override()/:set().
-- =====================================================================

----------------------------------------------------------------------
-- LOCALIZED HOT FUNCTIONS
----------------------------------------------------------------------
local floor, abs, min, max = math.floor, math.abs, math.min, math.max
local sin, cos, random, randomseed = math.sin, math.cos, math.random, math.randomseed

----------------------------------------------------------------------
-- BUILT-IN ANTI-AIM REFERENCES (verified paths from both scripts)
-- Each path is resolved safely; if a path is wrong it becomes nil instead
-- of crashing the script, and we record it for the diagnostic command.
----------------------------------------------------------------------
local missing_refs = {}

local function find(name, ...)
    local args = { ... }
    local okay, ref = pcall(function() return ui.find(unpack(args)) end)
    if okay and ref ~= nil then
        return ref
    end
    missing_refs[#missing_refs + 1] = name .. "  ->  " .. table.concat(args, " / ")
    return nil
end

local refs = {
    -- angles
    aa_enabled   = find("aa_enabled",   "Aimbot", "Anti Aim", "Angles", "Enabled"),
    pitch        = find("pitch",        "Aimbot", "Anti Aim", "Angles", "Pitch"),
    yaw          = find("yaw",          "Aimbot", "Anti Aim", "Angles", "Yaw"),
    yaw_base     = find("yaw_base",     "Aimbot", "Anti Aim", "Angles", "Yaw", "Base"),
    yaw_offset   = find("yaw_offset",   "Aimbot", "Anti Aim", "Angles", "Yaw", "Offset"),
    avoid_bs     = find("avoid_bs",     "Aimbot", "Anti Aim", "Angles", "Yaw", "Avoid Backstab"),
    yaw_mod      = find("yaw_mod",      "Aimbot", "Anti Aim", "Angles", "Yaw Modifier"),
    yaw_mod_off  = find("yaw_mod_off",  "Aimbot", "Anti Aim", "Angles", "Yaw Modifier", "Offset"),
    extended     = find("extended",     "Aimbot", "Anti Aim", "Angles", "Extended Angles"),
    -- body yaw / desync
    body_yaw     = find("body_yaw",     "Aimbot", "Anti Aim", "Angles", "Body Yaw"),
    left_limit   = find("left_limit",   "Aimbot", "Anti Aim", "Angles", "Body Yaw", "Left Limit"),
    right_limit  = find("right_limit",  "Aimbot", "Anti Aim", "Angles", "Body Yaw", "Right Limit"),
    inverter     = find("inverter",     "Aimbot", "Anti Aim", "Angles", "Body Yaw", "Inverter"),
    body_options = find("body_options", "Aimbot", "Anti Aim", "Angles", "Body Yaw", "Options"),
    body_freestd = find("body_freestd", "Aimbot", "Anti Aim", "Angles", "Body Yaw", "Freestanding"),
    -- freestanding
    freestand    = find("freestand",    "Aimbot", "Anti Aim", "Angles", "Freestanding"),
    -- misc aa
    fake_duck    = find("fake_duck",    "Aimbot", "Anti Aim", "Misc", "Fake Duck"),
    slow_walk    = find("slow_walk",    "Aimbot", "Anti Aim", "Misc", "Slow Walk"),
    leg_movement = find("leg_movement", "Aimbot", "Anti Aim", "Misc", "Leg Movement"),
    -- fake lag
    fake_lag     = find("fake_lag",     "Aimbot", "Anti Aim", "Fake Lag", "Enabled"),
    fake_limit   = find("fake_limit",   "Aimbot", "Anti Aim", "Fake Lag", "Limit"),
    -- ragebot exploits
    double_tap   = find("double_tap",   "Aimbot", "Ragebot", "Main", "Double Tap"),
    hide_shots   = find("hide_shots",   "Aimbot", "Ragebot", "Main", "Hide Shots"),
    hide_opts    = find("hide_opts",    "Aimbot", "Ragebot", "Main", "Hide Shots", "Options"),
    dt_lag       = find("dt_lag",       "Aimbot", "Ragebot", "Main", "Double Tap", "Lag Options"),
    -- movement (misc tab)
    air_strafe   = find("air_strafe",   "Miscellaneous", "Main", "Movement", "Air Strafe"),
    air_duck     = find("air_duck",     "Miscellaneous", "Main", "Movement", "Air Duck"),
}

-- Report missing references to console so we can fix wrong paths.
local function report_refs()
    if #missing_refs == 0 then
        print("[AA] All references resolved OK.")
    else
        print("[AA] " .. #missing_refs .. " reference(s) FAILED to resolve:")
        for i = 1, #missing_refs do
            print("  [X] " .. missing_refs[i])
        end
        print("[AA] Wrong paths = those features do nothing. Fix the path strings above.")
    end
end
report_refs()

-- Safe wrappers (paths may differ slightly between cheat versions)
local function ov(ref, value)
    if ref then pcall(function() ref:override(value) end) end
end
local function st(ref, value)
    if ref then pcall(function() ref:set(value) end) end
end
local function gt(ref)
    if ref then
        local okay, val = pcall(function() return ref:get() end)
        if okay then return val end
    end
    return nil
end

----------------------------------------------------------------------
-- STATE
----------------------------------------------------------------------
local antiaim = {
    frame = 0,
    flipped = false,
    last_flip = 0,
    spin = 0,

    pitch_modes = { "Down", "Up", "Fake Up", "Fake Down", "Zero", "Jitter" },
    yaw_modes   = { "Backward", "Static", "Spin", "Jitter" },
    mod_modes   = { "Disabled", "Center", "Offset", "Spin", "3-Way", "Random" },
    states      = { "Global", "Standing", "Moving", "Slow Walk", "Crouch", "Air", "Air Crouch" },
}

----------------------------------------------------------------------
-- TAB 1: MAIN
----------------------------------------------------------------------
local g_main = ui.create("AA » Main")
local m = {}
m.enabled      = g_main:switch("Enable Custom AA", true)
m.auto_enable  = g_main:switch("Auto-Enable Built-in AA", true)
m.preset       = g_main:combo("Preset", { "Custom", "UNHITTABLE", "Defensive Spam", "HvH Rage", "Defensive", "Legit" })
m.tickbase_ind = g_main:switch("Reset On New Round", true)
m.test_spin    = g_main:switch("TEST SPIN (debug)", false)

----------------------------------------------------------------------
-- TAB 2: ANGLES (per-state)
----------------------------------------------------------------------
local g_angles = ui.create("AA » Angles")
m.state_sel    = g_angles:combo("Edit State", antiaim.states)
m.state_active = g_angles:switch("State Enabled", true)
m.pitch        = g_angles:combo("Pitch", antiaim.pitch_modes)
m.yaw          = g_angles:combo("Yaw", antiaim.yaw_modes)
m.yaw_base     = g_angles:combo("Yaw Base", { "At Target", "Local View" })
m.yaw_offset   = g_angles:slider("Yaw Offset", -180, 180, 0)
m.yaw_mod      = g_angles:combo("Yaw Modifier", antiaim.mod_modes)
m.mod_offset   = g_angles:slider("Modifier Offset", -180, 180, 0)
m.spin_speed   = g_angles:slider("Spin Speed", 1, 60, 20)
m.jitter_range = g_angles:slider("Jitter Range", 1, 180, 60)

----------------------------------------------------------------------
-- TAB 3: DESYNC / BODY YAW
----------------------------------------------------------------------
local g_desync = ui.create("AA » Desync")
m.desync       = g_desync:switch("Desync (Body Yaw)", true)
m.left_limit   = g_desync:slider("Left Limit", 0, 60, 60)
m.right_limit  = g_desync:slider("Right Limit", 0, 60, 60)
m.body_opts    = g_desync:combo("Body Options", { "None", "Jitter", "Randomize Jitter", "Avoid Overlap" })
m.auto_inv     = g_desync:switch("Auto Inverter", true)
m.inv_speed    = g_desync:slider("Inverter Speed", 1, 30, 8)
m.extended     = g_desync:switch("Extended Angles", false)
m.fake_lag     = g_desync:switch("Fake Lag", true)
m.fake_limit   = g_desync:slider("Fake Lag Limit", 1, 16, 14)

----------------------------------------------------------------------
-- TAB 4: CONDITIONS (manual / freestand / backstab / roll)
----------------------------------------------------------------------
local g_cond = ui.create("AA » Conditions")
m.freestand    = g_cond:switch("Freestanding", false)
m.fs_body      = g_cond:switch("Body Freestanding", false)
m.edge_yaw     = g_cond:switch("Edge Yaw", false)
m.anti_backstab= g_cond:switch("Anti Backstab", true)
m.roll         = g_cond:switch("Roll (Fake Lean)", false)
m.roll_amount  = g_cond:slider("Roll Amount", -50, 50, 0)
m.manual_left  = g_cond:hotkey("Manual Left")
m.manual_right = g_cond:hotkey("Manual Right")
m.manual_back  = g_cond:hotkey("Manual Back")
m.manual_fwd   = g_cond:hotkey("Manual Forward")
m.manual_reset = g_cond:hotkey("Manual Reset")
m.manual_static= g_cond:switch("Manual Static", true)

----------------------------------------------------------------------
-- TAB 5: DEFENSIVE / EXPLOITS
----------------------------------------------------------------------
local g_def = ui.create("AA » Defensive")
m.defensive    = g_def:switch("Defensive AA", false)
m.def_pitch    = g_def:combo("Defensive Pitch", { "Down", "Up", "Zero" })
m.def_yaw      = g_def:combo("Defensive Yaw", { "Spin", "Sideways", "Backward", "Random" })
m.def_speed    = g_def:slider("Defensive Spin Speed", 1, 60, 25)
m.force_charge = g_def:switch("Force Charge", false)
m.disable_os   = g_def:switch("Remove Hide Shots on DT", false)

----------------------------------------------------------------------
-- TAB 6: MISC / MOVEMENT
----------------------------------------------------------------------
local g_misc = ui.create("AA » Misc")
m.nade_fix     = g_misc:switch("Grenade Fake-Duck Fix", true)
m.fast_ladder  = g_misc:switch("Fast Ladder", false)
m.air_strafe   = g_misc:switch("Force Air Strafe", false)
m.leg_anim     = g_misc:combo("Leg Movement", { "Default", "Always Slide", "Always Walk", "Off" })
m.slowwalk_key = g_misc:hotkey("Slow Walk Key")
m.fakeduck_key = g_misc:hotkey("Fake Duck Key")

----------------------------------------------------------------------
-- TAB 7: EXPLOITS (rage.exploit API)
----------------------------------------------------------------------
local g_exp = ui.create("AA » Exploits")
m.exp_enabled    = g_exp:switch("Enable Exploit Manager", false)
m.exp_autocharge = g_exp:switch("Auto Charge", true)
m.exp_charge_key = g_exp:hotkey("Force Charge Key")
m.exp_tp_key     = g_exp:hotkey("Force Teleport Key")
m.exp_min_charge = g_exp:slider("Min Charge to Shoot", 0, 100, 100)
m.exp_defensive  = g_exp:switch("Allow Defensive Discharge", true)
m.exp_block_def  = g_exp:switch("Block Defensive While Peeking", false)
m.exp_auto_peek  = g_exp:switch("Auto DT on Peek", false)
m.exp_dt_air     = g_exp:switch("DT Only in Air", false)
m.exp_hs_switch  = g_exp:switch("Auto Switch DT/HS", false)
m.exp_def_spam   = g_exp:switch("Defensive Spam (Anti-Tap)", false)
m.exp_def_pitch  = g_exp:combo("Def Tick Pitch", { "Jitter", "Down", "Up", "Zero" })
m.exp_def_yaw    = g_exp:combo("Def Tick Yaw", { "Jitter", "Spin", "Random", "Backward" })
-- NEW exploits not used elsewhere
m.exp_fd_def     = g_exp:switch("Fake-Duck Defensive", false)
m.exp_autopeek   = g_exp:switch("Auto Peek (shot & retreat)", false)
m.exp_autopeek_key = g_exp:hotkey("Auto Peek Key")
m.exp_autopeek_dist = g_exp:slider("Peek Distance", 50, 400, 180)
m.exp_doubletap_air = g_exp:switch("Air Double Tap (no slowdown)", false)

----------------------------------------------------------------------
-- PER-STATE STORAGE
----------------------------------------------------------------------
local stance_data = {}
for _, name in ipairs(antiaim.states) do
    stance_data[name] = {
        active = true, pitch = "Down", yaw = "Backward",
        yaw_base = "At Target", yaw_offset = 0,
        yaw_mod = "Center", mod_offset = 0,
        desync = true, left = 60, right = 60,
    }
end

local function save_current_state()
    local sel = m.state_sel:get()
    local s = stance_data[sel]
    if not s then return end
    s.active     = m.state_active:get()
    s.pitch      = m.pitch:get()
    s.yaw        = m.yaw:get()
    s.yaw_base   = m.yaw_base:get()
    s.yaw_offset = m.yaw_offset:get()
    s.yaw_mod    = m.yaw_mod:get()
    s.mod_offset = m.mod_offset:get()
    s.desync     = m.desync:get()
    s.left       = m.left_limit:get()
    s.right      = m.right_limit:get()
end

----------------------------------------------------------------------
-- STATE DETECTION
----------------------------------------------------------------------
local function get_player_state(me)
    local flags = me.m_fFlags
    local on_ground = bit.band(flags, bit.lshift(1, 0)) ~= 0
    local ducking   = bit.band(flags, bit.lshift(1, 1)) ~= 0
    local vel = me.m_vecVelocity:length2d()

    if not on_ground then
        return ducking and "Air Crouch" or "Air"
    elseif ducking then
        return "Crouch"
    elseif gt(refs.slow_walk) and vel > 1.5 then
        return "Slow Walk"
    elseif vel > 1.5 then
        return "Moving"
    else
        return "Standing"
    end
end

----------------------------------------------------------------------
-- ANTI-BACKSTAB
----------------------------------------------------------------------
local function check_backstab(me)
    local threat = entity.get_threat(false)
    if not threat or threat:is_dormant() then return false end
    local wep = threat:get_player_weapon()
    if not wep then return false end
    if wep:get_classname() ~= "CKnife" then return false end
    return me:get_origin():dist(threat:get_origin()) < 200
end

----------------------------------------------------------------------
-- MANUAL AA
----------------------------------------------------------------------
local manual_state = "none"
local manual_keys = { left = false, right = false, back = false, fwd = false, reset = false }
local manual_yaw_map = { left = -90, right = 90, back = 0, fwd = 180 }

local function update_manual()
    local function toggle(key, name)
        local pressed = m[key]:get()
        if pressed and not manual_keys[name] then
            manual_state = (manual_state == name) and "none" or name
        end
        manual_keys[name] = pressed
    end
    toggle("manual_left", "left")
    toggle("manual_right", "right")
    toggle("manual_back", "back")
    toggle("manual_fwd", "fwd")
    local rs = m.manual_reset:get()
    if rs and not manual_keys.reset then manual_state = "none" end
    manual_keys.reset = rs
end

----------------------------------------------------------------------
-- APPLY HELPERS
----------------------------------------------------------------------
local function apply_pitch(mode)
    if mode == "Jitter" then
        ov(refs.pitch, (floor(antiaim.frame) % 2 == 0) and "Down" or "Up")
    elseif mode == "Zero" then
        ov(refs.pitch, "Disabled")
    else
        ov(refs.pitch, mode)
    end
end

local function apply_yaw_modifier(mode, offset)
    if mode == "Spin" then
        ov(refs.yaw_mod, "Offset")
        ov(refs.yaw_mod_off, (antiaim.frame * m.spin_speed:get()) % 360 - 180)
    elseif mode == "Random" then
        randomseed(floor(antiaim.frame))
        ov(refs.yaw_mod, "Offset")
        ov(refs.yaw_mod_off, (random() * 2 - 1) * m.jitter_range:get())
    else
        ov(refs.yaw_mod, mode)
        ov(refs.yaw_mod_off, offset)
    end
end

local function apply_body_options(opt)
    if opt == "None" then
        ov(refs.body_options, {})
    elseif opt == "Jitter" then
        ov(refs.body_options, { "Jitter" })
    elseif opt == "Randomize Jitter" then
        ov(refs.body_options, { "Jitter", "Randomize Jitter" })
    elseif opt == "Avoid Overlap" then
        ov(refs.body_options, { "Avoid Overlap" })
    end
end

local function tick_inverter(speed)
    if (globals.tickcount - antiaim.last_flip) >= max(1, speed) then
        antiaim.flipped = not antiaim.flipped
        antiaim.last_flip = globals.tickcount
    end
    ov(refs.inverter, antiaim.flipped)
end

local function apply_desync(enabled, left, right)
    st(refs.body_yaw, enabled)
    if not enabled then return end
    ov(refs.left_limit, left)
    ov(refs.right_limit, right)
    apply_body_options(m.body_opts:get())
    ov(refs.body_freestd, m.fs_body:get() and "Peek Real" or nil)
    if m.auto_inv:get() then tick_inverter(m.inv_speed:get()) end
end

----------------------------------------------------------------------
-- FAKE LAG / EXTENDED
----------------------------------------------------------------------
local function apply_fake_lag()
    if m.fake_lag:get() then
        st(refs.fake_lag, true)
        ov(refs.fake_limit, m.fake_limit:get())
    end
    ov(refs.extended, m.extended:get() or nil)
end

----------------------------------------------------------------------
-- UNHITTABLE PRESET
----------------------------------------------------------------------
local function apply_unhittable()
    apply_fake_lag()

    -- pitch jitter
    ov(refs.pitch, (floor(antiaim.frame) % 2 == 0) and "Down" or "Fake Up")

    -- aggressive yaw jitter
    ov(refs.yaw, "Backward")
    ov(refs.yaw_base, "At Target")
    local jit = m.jitter_range:get()
    local side = (floor(antiaim.frame) % 2 == 0) and 1 or -1
    ov(refs.yaw_offset, side * (jit * 0.5))

    -- randomized modifier
    ov(refs.yaw_mod, "Offset")
    randomseed(floor(antiaim.frame))
    ov(refs.yaw_mod_off, (random() * 2 - 1) * jit)

    -- max desync + jitter options
    st(refs.body_yaw, true)
    ov(refs.left_limit, 60)
    ov(refs.right_limit, 60)
    ov(refs.body_options, { "Jitter", "Randomize Jitter" })
    ov(refs.extended, true)
    tick_inverter(min(m.inv_speed:get(), 2))
end

----------------------------------------------------------------------
-- DEFENSIVE TICK TRACKER (the real "unhittable" exploit)
-- Tracks tickbase to detect when you're in a defensive (lag-comp abuse)
-- window. During these ticks the enemy resolver can't pin your real
-- angle, so we jitter the hidden angle hard ONLY in that window.
----------------------------------------------------------------------
local defensive = {
    max_tickbase = 0,
    ticks_left = 0,
    active = false,
}

local function update_defensive_ticks(me)
    local dt_on = gt(refs.double_tap)
    local hs_on = gt(refs.hide_shots)
    local hs_breaklc = gt(refs.hide_opts) == "Break LC"
    local charged = rage.exploit:get() == 1

    -- only meaningful when an exploit that shifts tickbase is active
    if not charged or (not dt_on and not (hs_on and hs_breaklc)) then
        defensive.ticks_left = 0
        defensive.active = false
        return
    end

    local tb = me.m_nTickBase
    if abs(tb - defensive.max_tickbase) > 64 then
        defensive.max_tickbase = 0
    end
    if defensive.max_tickbase ~= 0 then
        defensive.ticks_left = min(14, max(0, defensive.max_tickbase - tb - 2))
    end
    defensive.max_tickbase = max(tb, defensive.max_tickbase)
    defensive.active = defensive.ticks_left > 0
end

----------------------------------------------------------------------
-- DEFENSIVE
----------------------------------------------------------------------
local function run_defensive()
    if not m.defensive:get() and m.preset:get() ~= "Defensive" then return end

    if m.force_charge:get() then
        rage.exploit:allow_charge(true)
        rage.exploit:force_charge()
    end
    if rage.exploit:get() < 1 then return end

    local pitch_val = ({ Down = 89, Up = -89, Zero = 0 })[m.def_pitch:get()] or 89
    local yaw_val
    local dy = m.def_yaw:get()
    if dy == "Spin" then
        yaw_val = (antiaim.frame * m.def_speed:get()) % 360 - 180
    elseif dy == "Sideways" then
        yaw_val = 90
    elseif dy == "Backward" then
        yaw_val = 180
    else
        randomseed(floor(antiaim.frame * 2))
        yaw_val = random(-180, 180)
    end
    rage.antiaim:override_hidden_pitch(pitch_val)
    rage.antiaim:override_hidden_yaw_offset(yaw_val)
end

----------------------------------------------------------------------
-- DEFENSIVE SPAM (real anti-tap exploit)
-- When defensive.active, the local player sits on shifted ticks the
-- enemy can't lag-compensate cleanly. We jitter the HIDDEN (real) angle
-- every defensive tick so a resolver gets a different real angle each
-- shot attempt -> this is what actually prevents getting tapped first.
----------------------------------------------------------------------
local function run_defensive_spam(me)
    if not m.exp_def_spam:get() then return end

    -- keep the exploit charged so we always have defensive windows
    rage.exploit:allow_charge(true)
    rage.exploit:allow_defensive(true)

    if not defensive.active then return end

    -- pitch on defensive ticks
    local p
    local pm = m.exp_def_pitch:get()
    if pm == "Jitter" then
        p = (floor(antiaim.frame) % 2 == 0) and 89 or -89
    elseif pm == "Down" then p = 89
    elseif pm == "Up" then p = -89
    else p = 0 end

    -- yaw on defensive ticks
    local y
    local ym = m.exp_def_yaw:get()
    if ym == "Jitter" then
        y = (floor(antiaim.frame) % 2 == 0) and 120 or -120
    elseif ym == "Spin" then
        y = (antiaim.frame * m.def_speed:get()) % 360 - 180
    elseif ym == "Random" then
        randomseed(floor(antiaim.frame * 3) + defensive.ticks_left)
        y = random(-180, 180)
    else
        y = 180
    end

    rage.antiaim:override_hidden_pitch(p)
    rage.antiaim:override_hidden_yaw_offset(y)
end

----------------------------------------------------------------------
-- EXPLOIT MANAGER (rage.exploit API from docs)
----------------------------------------------------------------------
local exploit = {
    state = 0,       -- internal cross-LC state machine
    charge_held = false,
}

local function run_exploit_manager(me, cmd)
    if not m.exp_enabled:get() then return end

    -- Auto charge: keep the exploit topped up
    if m.exp_autocharge:get() then
        rage.exploit:allow_charge(true)
    end

    -- Force charge hotkey
    if m.exp_charge_key:get() then
        rage.exploit:allow_charge(true)
        rage.exploit:force_charge()
    end

    -- Force teleport hotkey (recharge / reposition)
    if m.exp_tp_key:get() then
        rage.exploit:force_teleport()
    end

    -- Defensive discharge control
    rage.exploit:allow_defensive(m.exp_defensive:get())

    -- Block defensive while actively peeking (helps land first shot)
    if m.exp_block_def:get() then
        local threat = entity.get_threat(true)
        if threat ~= nil then
            rage.exploit:allow_defensive(false)
        end
    end

    local charge = rage.exploit:get()  -- [0,1]

    -- DT only in air: disable double tap on ground
    if m.exp_dt_air:get() then
        local on_ground = bit.band(me.m_fFlags, bit.lshift(1, 0)) ~= 0
        if on_ground then
            ov(refs.double_tap, false)
        else
            ov(refs.double_tap, nil)
        end
    end

    -- Auto DT on peek: enable double tap when a target is peekable
    if m.exp_auto_peek:get() then
        local threat = entity.get_threat(true)
        if threat ~= nil and charge >= 1 then
            ov(refs.double_tap, true)
        else
            ov(refs.double_tap, nil)
        end
    end

    -- Auto switch DT <-> HS based on charge & movement (exploit switch)
    if m.exp_hs_switch:get() then
        local vel = me.m_vecVelocity:length2d()
        local moving = vel > 5
        local on_ground = bit.band(me.m_fFlags, bit.lshift(1, 0)) ~= 0
        if charge >= 1 and not moving and on_ground then
            -- charged & still -> prefer hide shots
            ov(refs.double_tap, false)
            ov(refs.hide_shots, true)
        else
            ov(refs.double_tap, nil)
            ov(refs.hide_shots, nil)
        end
    end
end

----------------------------------------------------------------------
-- FAKE-DUCK DEFENSIVE (extends defensive window via fake duck)
----------------------------------------------------------------------
local function run_fakeduck_defensive(me, cmd)
    if not m.exp_fd_def:get() then return end
    -- enable fake duck to sit on shifted ticks longer
    st(refs.fake_duck, true)
    rage.exploit:allow_charge(true)
    -- during defensive ticks, jitter the hidden angle hard
    if defensive.active then
        local p = (floor(antiaim.frame) % 2 == 0) and 89 or -89
        local y = (floor(antiaim.frame) % 3 == 0) and 150 or -150
        rage.antiaim:override_hidden_pitch(p)
        rage.antiaim:override_hidden_yaw_offset(y)
    end
end

----------------------------------------------------------------------
-- AUTO PEEK (shoot then retreat using the exploit charge)
----------------------------------------------------------------------
local autopeek = { origin = nil, peeking = false }

local function run_auto_peek(me, cmd)
    if not m.exp_autopeek:get() then
        autopeek.origin = nil
        autopeek.peeking = false
        return
    end

    local key = m.exp_autopeek_key:get()
    local threat = entity.get_threat(true)

    if key then
        -- remember the safe spot the first frame the key is held
        if not autopeek.peeking then
            autopeek.origin = me:get_origin()
            autopeek.peeking = true
        end
        -- charge while peeking so we can fire instantly
        rage.exploit:allow_charge(true)
        rage.exploit:force_charge()
    elseif autopeek.peeking then
        -- key released: retreat back to the saved spot
        if autopeek.origin then
            local cur = me:get_origin()
            local dir = autopeek.origin - cur
            local dist = dir:length2d()
            if dist > 8 then
                local ang = math.atan2(dir.y, dir.x) * 180 / math.pi
                cmd.move_yaw = ang
                cmd.forwardmove = 450
            else
                autopeek.peeking = false
                autopeek.origin = nil
            end
        else
            autopeek.peeking = false
        end
    end
end

----------------------------------------------------------------------
-- GRENADE FAKE-DUCK FIX
----------------------------------------------------------------------
local function grenade_fix(me, cmd)
    if not m.nade_fix:get() then return end
    if not gt(refs.fake_duck) then return end
    local wep = me:get_player_weapon()
    if not wep then return end
    local info = wep:get_weapon_info()
    if not info or info.weapon_type ~= 9 then return end
    if wep.m_bPinPulled and wep.m_fThrowTime == 0 and me.m_flDuckAmount < 0.8 then
        cmd.in_attack = 1
    end
end

----------------------------------------------------------------------
-- MISC FEATURES
----------------------------------------------------------------------
local function apply_misc(me, cmd)
    -- disable hide shots on double tap
    if m.disable_os:get() and gt(refs.double_tap) and gt(refs.hide_shots) then
        st(refs.hide_shots, false)
    end

    -- force air strafe
    if m.air_strafe:get() then
        ov(refs.air_strafe, true)
    else
        ov(refs.air_strafe, nil)
    end

    -- leg movement
    local leg = m.leg_anim:get()
    if leg == "Always Slide" then
        ov(refs.leg_movement, "Sliding")
    elseif leg == "Always Walk" then
        ov(refs.leg_movement, "Walking")
    elseif leg == "Off" then
        ov(refs.leg_movement, "Off")
    else
        ov(refs.leg_movement, nil)
    end

    -- slow walk / fake duck hotkeys
    if m.slowwalk_key:get() then st(refs.slow_walk, true) end
    if m.fakeduck_key:get() then st(refs.fake_duck, true) end
end

-- Fast ladder (separate createmove logic)
local function fast_ladder(me, cmd)
    if not m.fast_ladder:get() or not me then return end
    if me.m_MoveType ~= 9 then return end -- 9 = MOVETYPE_LADDER
    if cmd.forwardmove == 0 then return end
    local cam = render.camera_angles()
    local up = cmd.forwardmove < 0 or cam.x > 45
    cmd.in_moveright = not up
    cmd.in_moveleft = up
    cmd.in_back = not up
    cmd.in_forward = up
    cmd.view_angles.x = 89
end

-- Roll / fake lean
local function apply_roll(cmd)
    if not m.roll:get() then return end
    local amt = m.roll_amount:get()
    if amt == 0 then amt = (floor(antiaim.frame) % 2 == 0) and 50 or -50 end
    cmd.view_angles.z = amt
end

----------------------------------------------------------------------
-- EDGE YAW (simplified trace-based, from wraith)
----------------------------------------------------------------------
local function apply_edge_yaw(me)
    if not m.edge_yaw:get() then return false end
    local fs_target = rage.antiaim:get_target(true)
    if fs_target == nil then return false end
    -- let the built-in freestanding handle edge detection
    ov(refs.freestand, true)
    return true
end

----------------------------------------------------------------------
-- MAIN LOOP
----------------------------------------------------------------------
events.createmove:set(function(cmd)
    save_current_state()
    update_manual()

    if not m.enabled:get() then return end

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

    if m.auto_enable:get() then
        ov(refs.aa_enabled, true)
    end
    ov(refs.avoid_bs, m.anti_backstab:get() or nil)

    antiaim.frame = antiaim.frame + 1
    if antiaim.frame > 360000 then antiaim.frame = 0 end

    -- TEST SPIN: unmistakable proof the script controls your AA.
    -- If this spins your real/fake angle, overrides work and the issue
    -- is just that "Custom" defaults matched your built-in settings.
    if m.test_spin:get() then
        ov(refs.aa_enabled, true)
        ov(refs.pitch, "Down")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_base, "Local View")
        ov(refs.yaw_mod, "Offset")
        ov(refs.yaw_mod_off, (antiaim.frame * 15) % 360 - 180)
        ov(refs.yaw_offset, (antiaim.frame * 15) % 360 - 180)
        st(refs.body_yaw, true)
        return
    end

    -- track defensive (lag-comp) window every tick
    update_defensive_ticks(me)

    -- always-run features
    run_defensive()
    run_defensive_spam(me)
    run_exploit_manager(me, cmd)
    run_fakeduck_defensive(me, cmd)
    run_auto_peek(me, cmd)
    grenade_fix(me, cmd)
    apply_misc(me, cmd)
    fast_ladder(me, cmd)
    apply_roll(cmd)

    local preset = m.preset:get()

    -- PRESET: UNHITTABLE
    if preset == "UNHITTABLE" then
        apply_unhittable()
        return
    end

    -- PRESET: Defensive Spam (real anti-tap exploit)
    if preset == "Defensive Spam" then
        apply_fake_lag()
        ov(refs.pitch, "Down")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_base, "At Target")
        ov(refs.yaw_offset, 0)
        ov(refs.yaw_mod, "Center")
        apply_desync(true, 60, 60)
        -- hidden jitter only fires during real defensive ticks
        if defensive.active then
            local p = (floor(antiaim.frame) % 2 == 0) and 89 or -89
            local y = (floor(antiaim.frame) % 2 == 0) and 120 or -120
            rage.antiaim:override_hidden_pitch(p)
            rage.antiaim:override_hidden_yaw_offset(y)
        end
        return
    end

    -- PRESET: HvH Rage (max desync + jitter + exploit charge)
    if preset == "HvH Rage" then
        apply_fake_lag()
        rage.exploit:allow_charge(true)
        ov(refs.pitch, (floor(antiaim.frame) % 2 == 0) and "Down" or "Fake Up")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_base, "At Target")
        ov(refs.yaw_offset, 0)
        ov(refs.yaw_mod, "3-Way")
        ov(refs.yaw_mod_off, m.jitter_range:get())
        apply_desync(true, 60, 60)
        ov(refs.body_options, { "Jitter", "Randomize Jitter" })
        ov(refs.extended, true)
        tick_inverter(2)
        return
    end

    -- PRESET: Legit (minimal, just slight desync)
    if preset == "Legit" then
        ov(refs.pitch, "Down")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_offset, 0)
        ov(refs.yaw_mod, "Disabled")
        apply_desync(true, 30, 30)
        return
    end

    -- fake lag / extended for custom mode
    apply_fake_lag()

    -- freestanding
    ov(refs.freestand, m.freestand:get() and rage.antiaim:get_target(true) ~= nil)

    -- anti-backstab takes priority
    if m.anti_backstab:get() and check_backstab(me) then
        ov(refs.pitch, "Down")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_base, "At Target")
        ov(refs.yaw_offset, 0)
        ov(refs.yaw_mod, "Disabled")
        apply_desync(true, 0, 0)
        return
    end

    -- manual aa
    if manual_state ~= "none" then
        ov(refs.pitch, "Down")
        ov(refs.yaw, "Backward")
        ov(refs.yaw_base, "Local View")
        ov(refs.yaw_offset, manual_yaw_map[manual_state] or 0)
        if m.manual_static:get() then
            ov(refs.yaw_mod, "Disabled")
        end
        apply_desync(m.desync:get(), m.left_limit:get(), m.right_limit:get())
        return
    end

    -- edge yaw
    apply_edge_yaw(me)

    -- resolve stance
    local state = get_player_state(me)
    local s = stance_data[state]
    if not s or not s.active then s = stance_data["Global"] end
    if not s.active then return end

    -- apply stance pitch
    apply_pitch(s.pitch)

    -- apply stance yaw
    if s.yaw == "Spin" then
        ov(refs.yaw, "Backward")
        ov(refs.yaw_offset, (antiaim.frame * m.spin_speed:get()) % 360 - 180)
    elseif s.yaw == "Jitter" then
        ov(refs.yaw, "Backward")
        ov(refs.yaw_offset, (floor(antiaim.frame) % 2 == 0)
            and s.yaw_offset + m.jitter_range:get() * 0.5
            or  s.yaw_offset - m.jitter_range:get() * 0.5)
    else
        ov(refs.yaw, s.yaw)
        ov(refs.yaw_offset, s.yaw_offset)
    end
    ov(refs.yaw_base, s.yaw_base)

    apply_yaw_modifier(s.yaw_mod, s.mod_offset)
    apply_desync(s.desync, s.left, s.right)
end)

----------------------------------------------------------------------
-- ON-SCREEN STATUS (so you can see if it's working without console)
----------------------------------------------------------------------
events.render:set(function()
    if not m.enabled:get() then return end
    local x, y = 12, 300
    local ok_count = 0
    for _ in pairs(refs) do ok_count = ok_count + 1 end
    ok_count = ok_count - #missing_refs

    local status_col = (#missing_refs == 0) and color(120, 255, 120) or color(255, 80, 80)
    render.text(2, vector(x, y), status_col, nil,
        ("[AA] refs OK: %d  | failed: %d"):format(ok_count, #missing_refs))

    local me = entity.get_local_player()
    if me and me:is_alive() then
        render.text(2, vector(x, y + 14), color(200, 200, 255), nil,
            ("preset: %s  | defensive: %s (%d)"):format(
                m.preset:get(),
                defensive.active and "YES" or "no",
                defensive.ticks_left or 0))

        -- READBACK: prove the override is actually landing
        local yaw_ov, pitch_ov = "nil", "nil"
        if refs.yaw_offset then
            local ok, v = pcall(function() return refs.yaw_offset:get_override() end)
            if ok and v ~= nil then yaw_ov = tostring(floor(v)) end
        end
        if refs.pitch then
            local ok, v = pcall(function() return refs.pitch:get_override() end)
            if ok and v ~= nil then pitch_ov = tostring(v) end
        end
        render.text(2, vector(x, y + 28), color(255, 230, 120), nil,
            ("override -> yaw_off: %s  pitch: %s"):format(yaw_ov, pitch_ov))
    end

    -- list up to 6 failed paths on screen
    for i = 1, math.min(#missing_refs, 6) do
        render.text(2, vector(x, y + 28 + (i - 1) * 12), color(255, 120, 120), nil,
            "X " .. missing_refs[i])
    end
end)

----------------------------------------------------------------------
-- CLEANUP ON UNLOAD
----------------------------------------------------------------------
events.shutdown:set(function()
    ov(refs.pitch, nil)
    ov(refs.yaw, nil)
    ov(refs.yaw_base, nil)
    ov(refs.yaw_offset, nil)
    ov(refs.avoid_bs, nil)
    ov(refs.yaw_mod, nil)
    ov(refs.yaw_mod_off, nil)
    ov(refs.left_limit, nil)
    ov(refs.right_limit, nil)
    ov(refs.inverter, nil)
    ov(refs.body_options, nil)
    ov(refs.body_freestd, nil)
    ov(refs.extended, nil)
    ov(refs.freestand, nil)
    ov(refs.aa_enabled, nil)
    ov(refs.air_strafe, nil)
    ov(refs.leg_movement, nil)
    ov(refs.double_tap, nil)
    ov(refs.hide_shots, nil)
    st(refs.fake_lag, false)
    ov(refs.fake_limit, nil)
end)
