var default_color = [158, 168, 255]
var default_color_a = [158, 168, 255, 255]
UI.AddHotkey(["Config", "Scripts", "JS Keybinds"], "Damage Override", "DMG Override");
UI.AddHotkey(["Config", "Scripts", "JS Keybinds"], "Hitchance Override", "Hitchance Override");
UI.AddHotkey(["Config", "Scripts", "JS Keybinds"], "Dormant Aim", "Dormant Aimbot");
UI.AddSubTab(["SUBTAB_MGR"], "Skyline Rage");
UI.AddSubTab(["SUBTAB_MGR"], "Skyline Visuals");
UI.AddSubTab(["SUBTAB_MGR"], "Skyline Misc");

function add(cat, name) {
    UI.AddCheckbox(["Skyline " + cat, "SHEET_MGR", "Skyline " + cat], name)
}
add("Rage", "Alternative fake-lags")
add("Rage", "Better auto-peek")
add("Rage", "Better double-tap")
add("Rage", "DMG override")
add("Rage", "Hitchance override")
add("Rage", "Slow-walk low-delta")
add("Rage", "R8 DT teleport")
add("Rage", "Dormant Aimbot Beta")
add("Visuals", "Indicators")
add("Visuals", "Small text size")
add("Visuals", "Grenade warning")
add("Visuals", "Grenade warning OOF")
add("Visuals", "Grenade warning line")
add("Visuals", "Revolver 100 DMG helper")
add("Visuals", "Hitmarker")
add("Visuals", "ESP Grenades")
add("Visuals", "Local bullet tracer")
add("Misc", "Leg fucker")
add("Misc", "Static legs in air")
//add("Misc", "Clantag")
Cheat.Print("----------------------------------\n")
Cheat.Print("--Skyline Cord [Coded by WendoX]--\n")
Cheat.Print("-----discord -> WendoX#0297-------\n")
Cheat.Print("-vk -> https://vk.com/retry_later-\n")
Cheat.Print("----------------------------------\n")
Cheat.Print("discord server -> https://discord.gg/3AfcqnTb4A\n")
Cheat.Print("----------------------------------\n")

var particles = []
var helper_dist = 50

function isEnabled(cat, name) {
    return UI.GetValue(["Skyline " + cat, "SHEET_MGR", name])
}
var wep2tab = {
    "usp s": "USP",
    "glock 18": "Glock",
    "dual berettas": "Dualies",
    "r8 revolver": "Revolver",
    "desert eagle": "Deagle",
    "p250": "P250",
    "tec 9": "Tec-9",
    "mp9": "MP9",
    "mac 10": "Mac10",
    "pp bizon": "PP-Bizon",
    "ump 45": "UMP45",
    "ak 47": "AK47",
    "sg 553": "SG553",
    "aug": "AUG",
    "m4a1 s": "M4A1-S",
    "m4a4": "M4A4",
    "ssg 08": "SSG08",
    "awp": "AWP",
    "g3sg1": "G3SG1",
    "scar 20": "SCAR20",
    "xm1014": "XM1014",
    "mag 7": "MAG7",
    "m249": "M249",
    "negev": "Negev",
    "p2000": "General",
    "famas": "FAMAS",
    "five seven": "Five Seven",
    "mp7": "MP7",
    "ump 45": "UMP45",
    "p90": "P90",
    "cz75 auto": "CZ-75",
    "mp5 sd": "MP5",
    "galil ar": "GALIL",
    "sawed off": "Sawed off"
};
const trace_type = 0x1 | 0x4000 | 0x2 | 0x2000000 | 0x8 | 0x80000
var tab_names = ["General", "USP", "Glock", "Five Seven", "Tec-9", "Deagle", "Revolver", "Dualies", "P250", "CZ-75", "Mac10", "P90", "MP5", "MP7", "MP9", "UMP45", "PP-Bizon", "M4A1-S", "M4A4", "AK47", "AUG", "SG553", "FAMAS", "GALIL", "AWP", "SSG08", "SCAR20", "G3SG1", "M249", "XM1014", "MAG7", "Negev", "Sawed off"];
var dir = [-24, 0]
var scout_autostop = UI.GetValue(["Rage", "Accuracy", "SSG08", "Auto stop mode"]);
var awp_autostop = UI.GetValue(["Rage", "Accuracy", "AWP", "Auto stop mode"]);
var r8_autostop = UI.GetValue(["Rage", "Accuracy", "Revolver", "Auto stop mode"]);

var scout_sp = UI.GetValue(["Rage", "Accuracy", "SSG08", "Prefer safe point"]);
var awp_sp = UI.GetValue(["Rage", "Accuracy", "AWP", "Prefer safe point"]);
var r8_sp = UI.GetValue(["Rage", "Accuracy", "Revolver", "Prefer safe point"]);
var lines = []
var hits = []
var pmolotov = []
var tracer_lines = []
var altfakelag = 0;
var setid = "m_nForceBone"
var name = "m_nBody"
var name2 = "CBaseCSGrenadeProjectile"

function setup_menu() {
    for (k in tab_names) {
        UI.AddSliderInt(["Rage", "Target", tab_names[k]], "Damage Override", 1, 130);
        UI.AddSliderInt(["Rage", "Target", tab_names[k]], "Hitchance Override", 1, 99);
    }
}

setup_menu()
var hotkeys = []
const indicator = {
    name: "",
    fade: 0,
    draw: function(x, y) {},
    enabled: function() {
        return true
    },
    color: function() {
        return default_color
    },
    centered: 0
}
init()
Render.Arc = function(x, y, radius, radius_inner, start_angle, end_angle, segments, color) {
    while (360 % segments != 0) {
        segments++;
    }
    segments = 360 / segments;
    for (var i = start_angle; i < start_angle + end_angle; i = i + segments) {
        var rad = i * Math.PI / 180;
        var rad2 = (i + segments) * Math.PI / 180;
        var rad_cos = Math.cos(rad);
        var rad_sin = Math.sin(rad);
        var rad2_cos = Math.cos(rad2);
        var rad2_sin = Math.sin(rad2);
        var x1_outer = x + rad_cos * radius;
        var y1_outer = y + rad_sin * radius;
        var x2_outer = x + rad2_cos * radius;
        var y2_outer = y + rad2_sin * radius;
        var x1_inner = x + rad_cos * radius_inner;
        var y1_inner = y + rad_sin * radius_inner;
        var x2_inner = x + rad2_cos * radius_inner;
        var y2_inner = y + rad2_sin * radius_inner;
        Render.Polygon([
            [x1_outer, y1_outer],
            [x2_outer, y2_outer],
            [x1_inner, y1_inner]
        ], color);
        Render.Polygon([
            [x1_inner, y1_inner],
            [x2_outer, y2_outer],
            [x2_inner, y2_inner]
        ], color);
    }
}
Math.clamp = function(num, min, max) {
    return num <= min ? min : num >= max ? max : num;
}

const vectorDistance = function(vec, vec2) {
    dx = vec[0] - vec2[0]
    dy = vec[1] - vec2[1]
    dz = vec[2] - vec2[2]
    return Math.abs(Math.sqrt(dx * dx + dy * dy + dz * dz));
}

function check_revolver_distance(victim) {
    player = Entity.GetLocalPlayer()
    if (player == null || victim == null)
        return;

    const weap = Entity.GetWeapon(player)
    if (weap == null)
        return;

    const player_origin = Entity.GetRenderOrigin(player)
    const victim_origin = Entity.GetRenderOrigin(victim)

    const units = vectorDistance(player_origin, victim_origin)
    const no_kevlar = Entity.GetProp(victim, "CCSPlayerResource", "m_iArmor") == 0

    if (Entity.GetName(weap) != "r8 revolver" || !no_kevlar)
        return false


    if (units < 585 && units > 511)
        return true

    else if (units < 511)
        return true
    else
        return false
}
var recharge
var r8dt

function hurt() {
    if (isEnabled("Visuals", "Hitmarker")) {
        attacker = Event.GetInt("attacker");
        index = Entity.GetEntityFromUserID(attacker);
        user_id = Event.GetInt("userid");
        user = Entity.GetEntityFromUserID(user_id);
        if (index == Entity.GetLocalPlayer() && index != user) {
            var pos = Entity.GetHitboxPosition(user, Event.GetInt("hitgroup"))
            if (pos == undefined) {
                pos = Entity.GetRenderOrigin(user)
                pos[2] = pos[2] + 30
            }
            pos[0] = (pos[0] - 10) + (Math.random() * 20)
            pos[1] = (pos[1] - 10) + (Math.random() * 20)
            pos[2] = (pos[2] - 15) + (Math.random() * 30)
            particles.push([pos, Globals.Tickcount() + 350, Event.GetInt("dmg_health")])
        }
    }
}

function tick() {
    isEnabled("Misc", "Leg fucker") && (trufalse = 10 * Math.abs(Math.sin(64 * Globals.Realtime())), trufalse > 5 && UI.SetValue(["Misc.", "Movement", "Leg movement"], 0), trufalse < 5 && UI.SetValue(["Misc.", "Movement", "Leg movement"], 1))
    if (isEnabled("Rage", "Better double-tap")) {
        var exploitCharge = Exploit.GetCharge();
        Exploit[(1 != exploitCharge ? "Enable" : "Disable") + "Recharge"](), Exploit.OverrideMaxProcessTicks(19), Exploit.OverrideShift(19)
        Exploit.OverrideTolerance(0), can_shift_shot(12) && 1 != exploitCharge && (Exploit.DisableRecharge(), Exploit.Recharge())
    } else {
        Exploit.EnableRecharge(), Exploit.OverrideShift(12), Exploit.OverrideTolerance(3)
    }
    if (isr8() && isEnabled("Rage", "R8 DT teleport")) {
        if (r8dt && recharge + 20 == Globals.Tickcount()) {
            UI.ToggleHotkey(["Rage", "Exploits", "Keys", "Key assignment", "Double tap"])
            r8dt = false
        }
    }
    if (isEnabled("Rage", "Alternative fake-lags")) {
        var ab = function(a, b) {

            return a < b

        }

        ab(altfakelag, 15 - 1) ? (UserCMD.Choke(), altfakelag++) : altfakelag < 14 + 8 ? (UserCMD.Send(), altfakelag++) : altfakelag = 0;
    }
    if (isEnabled("Visuals", "Hitmarker")) {
        for (var i = 0; i < particles.length; i++) {
            object = particles[i]
            var delta = object[1] - Globals.Tickcount()
            if (delta > 0) {
                object[0][2] += 0.3
            }
        }
    }
    if (UI.GetValue(["Rage", "Anti Aim", "General", "Key assignment", "Slow walk"])) {
        if (isEnabled("Rage", "Slow-walk low-delta")) {
            AntiAim.SetOverride(1);
            AntiAim.SetRealOffset(dir[0])
            AntiAim.SetFakeOffset(dir[1])
        }
    } else {
        if (isEnabled("Rage", "Slow-walk low-delta")) {
            AntiAim.SetOverride(0);
        }
    }
    if (isEnabled("Rage", "Better auto-peek")) {
        if (UI.GetValue(["Misc.", "Keys", "Key assignment", "Auto peek"]) && UI.GetValue(["Config", "Scripts", "JS Keybinds", "Damage Override"]) && UI.GetValue(["Rage", "Exploits", "Key assignment", "Double tap"])) {
            UI.SetValue(["Rage", "Accuracy", "SSG08", "Auto stop mode"], 2);
            UI.SetValue(["Rage", "Accuracy", "Revolver", "Auto stop mode"], 2);
            UI.SetValue(["Rage", "Accuracy", "AWP", "Auto stop mode"], 2);
            UI.SetValue(["Rage", "Accuracy", "SSG08", "Prefer safe point"], 1);
            UI.SetValue(["Rage", "Accuracy", "AWP", "Prefer safe point"], 1);
            UI.SetValue(["Rage", "Accuracy", "Revolver", "Prefer safe point"], 1);
            UI.SetValue(["Rage", "Anti Aim", "Directions", "Auto direction"], 1);
        } else {
            UI.SetValue(["Rage", "Accuracy", "SSG08", "Auto stop mode"], scout_autostop);
            UI.SetValue(["Rage", "Accuracy", "AWP", "Auto stop mode"], awp_autostop);
            UI.SetValue(["Rage", "Accuracy", "Revolver", "Auto stop mode"], r8_autostop);
            UI.SetValue(["Rage", "Accuracy", "SSG08", "Prefer safe point"], scout_sp);
            UI.SetValue(["Rage", "Accuracy", "AWP", "Prefer safe point"], awp_sp);
            UI.SetValue(["Rage", "Accuracy", "Revolver", "Prefer safe point"], r8_sp);
            UI.SetValue(["Rage", "Anti Aim", "Directions", "Auto direction"], 0);
        }
    }

    if (isEnabled("Visuals", "Indicators")) {
        update_indicators()
    }
    if (UI.GetValue(["Config", "Scripts", "JS Keybinds", "Damage Override"]) && isEnabled("Rage", "DMG override")) {
        var tab = wep2tab[Entity.GetName(Entity.GetWeapon(Entity.GetLocalPlayer()))];
        if (tab == undefined) {
            tab = "General";
        }
        var override = UI.GetValue(["Rage", "Target", tab, "Damage Override"]);
        if (override == 0 && tab != "General") {
            override = UI.GetValue(["Rage", "Target", "General", "Damage Override"])
        }
        var target = Entity.GetEnemies();
        for (var i in target) {
            Ragebot.ForceTargetMinimumDamage(target[i], override)
        }
    }
    if (UI.GetValue(["Config", "Scripts", "JS Keybinds", "Hitchance Override"]) && isEnabled("Rage", "Hitchance override")) {
        var tab = wep2tab[Entity.GetName(Entity.GetWeapon(Entity.GetLocalPlayer()))];
        if (tab == undefined) {
            tab = "General";
        }
        var override = UI.GetValue(["Rage", "Target", tab, "Hitchance Override"]);
        if (override == 0 && tab != "General") {
            override = UI.GetValue(["Rage", "Target", "General", "Hitchance Override"])
        }
        var target = Entity.GetEnemies();
        for (var i in target) {
            Ragebot.ForceTargetHitchance(target[i], override);
        }
    }
    if (isEnabled("Visuals", "Revolver 100 DMG helper")) {
        enemies = Entity.GetEnemies();

        for (i = 0; i < enemies.length; i++) {
            if (Entity.IsAlive(enemies[i])) {
                if (check_revolver_distance(enemies[i])) {
                    Entity.DrawFlag(enemies[i], "R8 100 DMG", [158, 168, 255, 255])
                }
            }
        }
    }
    if (UI.GetValue(["Config", "Scripts", "JS Keybinds", "Dormant Aim"]) && isEnabled("Rage", "Dormant Aimbot Beta")) {
        dormant_aim()
    }
    grenade_warning_tick()
    var buttons = UserCMD.GetButtons()
    const check = function(v) {
        return !(buttons & v)
    }
    if(check(1) && check(32) && check(16777216) && check(8192) && check(2048) && check(4) && !check(2) && isEnabled("Misc", "Static legs in air")) {
        UserCMD.SetButtons(512)
    }
}
function dtr(degress) {
    return degress * Math.PI / 180.0;
}

function rtd(radians) {
    return radians * 180 / Math.PI
}

function deg(vec1, vec2) {
    x = vec2[0] - vec1[0]
    z = vec2[1] - vec1[1]
    y = vec1[2] - vec2[2]
    return [rtd(Math.atan2(z, x)), rtd(Math.atan2(y, Math.sqrt(x * x + z * z)))]
}

function dormant_aim() {
    enemies = Entity.GetEnemies();
    for (i = 0; i < enemies.length; i++) {
        if (Entity.IsAlive(enemies[i]) && Entity.IsDormant(enemies[i])) {
            var startPos = Entity.GetHitboxPosition(Entity.GetLocalPlayer(), 0)
            var endPos = Entity.GetRenderOrigin(enemies[i])
            endPos[2] = endPos[2] + 38
            var trace_result = Trace.Bullet(Entity.GetLocalPlayer(), enemies[i], startPos, endPos);
            if (trace_result[1] > 0) {
                var arr = deg(startPos, endPos);
                var yaw = arr[0]
                var pitch = arr[1]
                if (Local.GetInaccuracy() < 0.01) {
                    UserCMD.SetViewAngles([pitch, yaw, 0], true)
                    UserCMD.SetButtons(UserCMD.GetButtons | 1)
                }
            }
        }
    }
}

function swap() {
    var rand = Math.random()
    if (rand > 0.0 && rand < 0.5) {
        dir = [-28, 0]
    }
    if (rand > 0.5 && rand < 1) {
        dir = [0, 0]
    }
    if ((Entity.GetEntityFromUserID(Event.GetInt("userid")) != Entity.GetLocalPlayer()) || !isr8()) return;
    recharge = Globals.Tickcount();
    if (UI.GetValue(["Rage", "Exploits", "Keys", "Key assignment", "Double tap"]) && isEnabled("Rage", "R8 DT teleport")) {
        UI.ToggleHotkey(["Rage", "Exploits", "Keys", "Key assignment", "Double tap"])
        r8dt = true;
    }
}

function can_shift_shot(ticks_to_shift) {
    var me = Entity.GetLocalPlayer();
    var wpn = Entity.GetWeapon(me);

    if (me == null || wpn == null)
        return false;

    var tickbase = Entity.GetProp(me, "CCSPlayer", "m_nTickBase");
    var curtime = Globals.TickInterval() * (tickbase - ticks_to_shift)

    if (curtime < Entity.GetProp(me, "CCSPlayer", "m_flNextAttack"))
        return false;

    if (curtime < Entity.GetProp(wpn, "CBaseCombatWeapon", "m_flNextPrimaryAttack"))
        return false;

    return true;
}

function calcDist(local, target) {
    var lx = local[0];
    var ly = local[1];
    var lz = local[2];
    var tx = target[0];
    var ty = target[1];
    var tz = target[2];
    var dx = lx - tx;
    var dy = ly - ty;
    var dz = lz - tz;
    return Math.sqrt(dx * dx + dy * dy + dz * dz);
}

function isr8() {
    return Entity.GetName(Entity.GetWeapon(Entity.GetLocalPlayer())) == "r8 revolver"
}


function angle_to_vec(pitch, yaw) {
    var p = degreesToRadians(pitch);
    var y = degreesToRadians(yaw)
    var sin_p = Math.sin(p);
    var cos_p = Math.cos(p);
    var sin_y = Math.sin(y);
    var cos_y = Math.cos(y);
    return [cos_p * cos_y, cos_p * sin_y, -sin_p];
}

function degreesToRadians(degress) {
    return degress * Math.PI / 180.0;
}

function idToStr(name) {
    if (name == "molotov") {
        return "O"
    }
    if (name == "high explosive grenade") {
        return "j"
    }
    if (name == "smoke grenade") {
        return "Z"
    }
    if (name == "incendiary grenade") {
        return "l"
    }
    return "";
}
var lasttime = 0
var setNull

function draw() {
    if(World.GetServerString() == "") {
    hits = []
    lines = []
    particles = []
    tracer_lines = []
    pmolotov = []
    }
    enemies = Entity.GetEnemies();
    for (i = 0; i < enemies.length; i++) {
        if (Entity.IsAlive(enemies[i]) && !Entity.IsDormant(enemies[i]) && isEnabled("Visuals", "ESP Grenades")) {
            var pos = Entity.GetRenderBox(enemies[i])
            var x = (pos[3] - pos[1]) / 2
            x += pos[1]
            str = ""
            for (var b = 0; b < Entity.GetWeapons(enemies[i]).length; b++) {
                str += idToStr(Entity.GetName(Entity.GetWeapons(enemies[i])[b]))
            }
            var font_nade = Render.GetFont("skyline/weaponicons.ttf", 20, false);
            Render.String(x - 1, pos[2] - 34, 1, str, [25, 25, 25, 255], font_nade)
            Render.String(x, pos[2] - 33, 1, str, [255, 255, 255, 255], font_nade)
        }
    }
    var local = Entity.GetLocalPlayer();
    if (isEnabled("Visuals", "Local bullet tracer") && UI.GetValue(["Misc.", "Keys", "Key assignment", "Thirdperson"])) {
        for (var i = 0; i < tracer_lines.length; i++) {
            object = tracer_lines[i]
            var delta = object[2] - Globals.Tickcount()
            var xz1 = Render.WorldToScreen(object[0])
            var xz2 = Render.WorldToScreen(object[1])
            if (delta > 0) {
                size = Render.GetScreenSize()
                delta = delta * 5
                if (delta > 255) {
                    delta = 255
                }
                Render.Line(xz1[0], xz1[1], xz2[0], xz2[1], [158, 168, 255, delta])
                Render.FilledCircle(xz2[0], xz2[1], 3, [158, 168, 255, delta])
            }
        }
    }
    if (Entity.IsAlive(local)) {
        if (isEnabled("Visuals", "Indicators")) {
            draw_indicators()
            var desync_delta = Math.clamp(Math.abs(Math.round(Local.GetRealYaw() - Local.GetFakeYaw())), 0, 58)
            Render.GradientRect((Global.GetScreenSize()[0] / 2 + -desync_delta * 2) + desync_delta + 2, Global.GetScreenSize()[1] / 2 + 26, desync_delta, 2.5, 1, [158, 168, 255, 0], [158, 168, 255, 255]);
            Render.GradientRect((Global.GetScreenSize()[0] / 2 + -desync_delta * 2) + (desync_delta * 2), Global.GetScreenSize()[1] / 2 + 26, desync_delta, 2.5, 1, [158, 168, 255, 255], [158, 168, 255, 0]);
            var fonT = isEnabled("Visuals", "Small text size") ? porter(11) : small(15)
            var comp = (isEnabled("Visuals", "Small text size") ? 2 : 0)
            Render.String(resolution[0] / 2, resolution[1] / 2 + 12 - comp, 1, desync_delta + "", [25, 25, 25, 255], fonT)
            Render.String(resolution[0] / 2, resolution[1] / 2 + 11 - comp, 1, desync_delta + "", [158, 168, 255, 255], fonT)
        }
        if (isEnabled("Visuals", "Revolver 100 DMG helper")) {
            size = Render.GetScreenSize()
            enemies = Entity.GetEnemies();
            for (i = 0; i < enemies.length; i++) {
                if (Entity.IsAlive(enemies[i])) {
                    origin = Entity.GetHitboxPosition(enemies[i], 0);
                    if (origin) {
                        xz = Render.WorldToScreen(origin)
                        if (check_revolver_distance(enemies[i])) {
                            Render.Line(size[0] / 2, size[1], xz[0], xz[1], [158, 168, 255, 255]);
                        }
                    }
                }
            }
        }
        if (isEnabled("Visuals", "Hitmarker")) {
            for (var i = 0; i < particles.length; i++) {
                pos = Render.WorldToScreen(particles[i][0])
                var timer = particles[i][1] - Globals.Tickcount()
                if (timer > 255) {
                    timer = 255
                }
                if (!(timer < 0)) {
                    if (pos != undefined) {
                        Render.String(pos[0], pos[1], 1, particles[i][2].toString(), [158, 168, 255, timer], small(20))
                    }
                }
            }
        }
    } else {
        hits = []
        particles = []
        lines = []
        pmolotov = []
    }
    if (isEnabled("Visuals", "Grenade warning")) {
        grenade_warning_draw()
    }
}

function draw_indicators() {
    resolution = Render.GetScreenSize()
    var m = 0
    var down = 23
    for (var i = 0; i < hotkeys.length; i++) {
        var ind = hotkeys[i]
        if (ind.fade > 0) {
            var comp = (isEnabled("Visuals", "Small text size") ? 4 : 0)
            Render.String(resolution[0] / 2 + 1 - ind.centered, resolution[1] / 2 + 10 + (m * 13.5) + down - comp, 1, ind.name, [25, 25, 25, ind.fade * 10], porter(13))
            Render.String(resolution[0] / 2 - ind.centered, resolution[1] / 2 + 9 + (m * 13.5) + down - comp, 1, ind.name, [ind.color()[0], ind.color()[1], ind.color()[2], ind.fade * 10], porter(13))
            ind.draw(resolution[0] / 2, resolution[1] / 2 + 9 + (m * 13.5) + down, ind.fade * 10)
            m++
        }
    }
}


function update_indicators() {
    for (var i = 0; i < hotkeys.length; i++) {
        var ind = hotkeys[i]
        if (ind.enabled()) {
            ind.fade = ind.fade + 2
            ind.fade = Math.clamp(ind.fade, 0, 25)
        } else {
            ind.fade = ind.fade - 2
            ind.fade = Math.clamp(ind.fade, 0, 25)
        }
    }
}
function getLocal() {
    return Entity.GetRenderOrigin(Entity.GetLocalPlayer());
}
function porter(size) {
    if (isEnabled("Visuals", "Small text size")) {
        return Render.GetFont("Verdana.ttf", size, true);
    }
    return Render.GetFont("skyline/porter.ttf", size, false);
}

function small(size) {
    return Render.GetFont("skyline/samson.ttf", size, false);
}

function debug(value) {
    Cheat.PrintColor([255, 255, 255, 255], value.toString() + "\n")
}

function init() {
    dt = Object.create(indicator)
    dt.name = "DT"
    dt.enabled = function() {
        return UI.GetValue(["Rage", "Exploits", "Key assignment", "Double tap"])
    }
    dt.color = function() {
        return [158, 168, 255, 255]
    }
    dt.draw = function(x, y, fade) {
        var charg = Math.clamp(charge() - 0.2, 0, 1)
        if (charg < 0.1)
            charg = 0
        Render.Arc(x + 8.5, y + 3.8, 3, 2, 0, 360, 15, [20, 20, 20, fade])
        Render.Arc(x + 8.5, y + 3.8, 3, 2, 0, charg * 440, 15, [158, 168, 255, fade])
    }
    dt.centered = 4
    hide = Object.create(indicator)
    hide.name = "HIDE"
    hide.enabled = function() {
        return UI.GetValue(["Rage", "Exploits", "Key assignment", "Hide shots"])
    }
    safe = Object.create(indicator)
    safe.name = "SAFE"
    safe.enabled = function() {
        return UI.GetValue(["Rage", "General", "Key assignment", "Force safe point"])
    }
    low_delta = Object.create(indicator)
    low_delta.name = "LOW-DELTA"
    low_delta.enabled = function() {
        return UI.GetValue(["Rage", "Anti Aim", "General", "Key assignment", "Slow walk"]) && isEnabled("Rage", "Slow-walk low-delta")
    }
    dmg = Object.create(indicator)
    dmg.name = "DMG"
    dmg.enabled = function() {
        return UI.GetValue(["Config", "Scripts", "JS Keybinds", "Damage Override"]) && isEnabled("Rage", "DMG override")
    }
    hc = Object.create(indicator)
    hc.name = "HC"
    hc.enabled = function() {
        return UI.GetValue(["Config", "Scripts", "JS Keybinds", "Hitchance Override"]) && isEnabled("Rage", "Hitchance override")
    }
    da = Object.create(indicator)
    da.name = "DA"
    da.enabled = function() {
        return UI.GetValue(["Config", "Scripts", "JS Keybinds", "Dormant Aim"]) && isEnabled("Rage", "Dormant Aimbot Beta")
    }
    hotkeys.push(dt)
    hotkeys.push(dmg)
    hotkeys.push(hc)
    hotkeys.push(hide)
    hotkeys.push(safe)
    hotkeys.push(low_delta)
    hotkeys.push(da)
}

function charge() {
    return Exploit.GetCharge()
}

function on_player_connect() {
    lines = []
    hits = []
    pmolotov = []
}
var id = 1

function grenade_warning_tick() {
    entities = Entity.GetEntitiesByClassID(9).concat(Entity.GetEntitiesByClassID(114));
    for (var i = 0; i < entities.length; i++) {
        entity = entities[i]
        if (Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_nExplodeEffectTickBegin') == 0) {
            Entity.SetProp(entity, name2, name, Entity.GetProp(entity, name2, name) + 1)
        }
    }
    if (entities.length == 0) {
        hits = []
        lines = []
        pmolotov = []
    }
    entities = Entity.GetEntitiesByClassID(9)
    for (var i = 0; i < entities.length; i++) {
        entity = entities[i]
        var vel = Entity.GetProp(entity, 'CBaseGrenade', 'm_vecVelocity');
        if (Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime') != Math.round(vel[0]) && Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_nExplodeEffectTickBegin') == 0) {
            Entity.SetProp(entity, 'CBaseCSGrenade', 'm_flAnimTime', Math.round(vel[0]))
            var mx = vel[0] * 0.015
            var my = vel[2] * 0.015
            var mz = vel[1] * 0.015
            Entity.SetProp(entity, 'CBaseCSGrenadeProjectile', setid, id)
            id++
            var x = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[0]
            var y = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[2]
            var z = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[1]
            var hittable = false
            for (var i = 0; i < 109 - Entity.GetProp(entity, name2, name); i++) {
                my = my - 0.0712
                var hit = []
                var hitbox = [
                    [
                        [x - 2, z - 2, y - 2],
                        [x + mx - 2, z + mz - 2, y + my - 2]
                    ],
                    [
                        [x - 2, z - 2, y + 2],
                        [x + mx - 2, z + mz - 2, y + my + 2]
                    ],
                    [
                        [x + 2, z + 2, y - 2],
                        [x + mx + 2, z + mz + 2, y + my - 2]
                    ],
                    [
                        [x + 2, z + 2, y + 2],
                        [x + mx + 2, z + mz + 2, y + my + 2]
                    ]
                ]
                for (var v = 0; v < hitbox.length; v++) {
                    var h = hitbox[v]
                    var res = 0
                    res = Trace.Line(entity, h[0], h[1])[1]
                    if (res != 1) {
                        var ny = h[0][2] + 10
                        var nx = h[1][0]
                        var nz = h[1][1]
                        var fny = h[0][2]
                        var fnx = h[1][0]
                        var fnz = h[1][1]
                        vres = Trace.Line(entity, [fnx, fnz, fny], [nx, nz, ny])[1]
                        var start = [x, z, y]
                        var end = [x - mx, z - mz, y - 30]
                        vres1 = Trace.Line(entity, start, end)[1]
                        if (vres == 1 && vres1 == 1) {
                            hittable = true
                            hit = [x + mx * (res), z + mz * (res), y + my * (res)]
                            break;
                        } else {
                            my = my * -0.45
                            mx = mx * 0.45
                            mz = mz * 0.45
                            break
                        }
                    }
                }
                if (hit.length > 1) {
                    hits.push([
                        [hit[0], hit[1], hit[2]], Globals.Tickcount() + i, false, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime'), Globals.Tickcount()
                    ])
                    break;
                }
                if (i % (isEnabled("Visuals", "Grenade warning line") ? 1 : 2) == 0) {
                    lines.push([
                        [x, z, y],
                        [x + mx, z + mz, y + my], Globals.Tickcount() + i, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime')
                    ])
                }
                x = x + mx
                y = y + my
                z = z + mz
            }
            if (!hittable) {
                hits.push([
                    [x, z, y], Globals.Tickcount() + i, false, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime'), Globals.Tickcount()
                ])
            }
        }
    }
    entities = Entity.GetEntitiesByClassID(114)
    for (var i = 0; i < entities.length; i++) {
        entity = entities[i]

        var vel = Entity.GetProp(entity, 'CBaseGrenade', 'm_vecVelocity');
        if (Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime') != Math.round(vel[0]) && Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_nExplodeEffectTickBegin') == 0) {
            Entity.SetProp(entity, 'CBaseCSGrenade', 'm_flAnimTime', Math.round(vel[0]))
            var mx = vel[0] * 0.015
            var my = vel[2] * 0.015
            var mz = vel[1] * 0.015
            Entity.SetProp(entity, 'CBaseCSGrenadeProjectile', setid, id)
            id++
            var predicted
            var x = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[0]
            var y = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[2]
            var z = Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_vecOrigin')[1]
            var hittable = false
            for (var i = 0; i < 130 - Entity.GetProp(entity, name2, name); i++) {
                my = my - 0.0712
                var hit = []
                var hitbox = [
                    [
                        [x - 2, z - 2, y - 2],
                        [x + mx - 2, z + mz - 2, y + my - 2]
                    ],
                    [
                        [x - 2, z - 2, y + 2],
                        [x + mx - 2, z + mz - 2, y + my + 2]
                    ],
                    [
                        [x + 2, z + 2, y - 2],
                        [x + mx + 2, z + mz + 2, y + my - 2]
                    ],
                    [
                        [x + 2, z + 2, y + 2],
                        [x + mx + 2, z + mz + 2, y + my + 2]
                    ]
                ]
                for (var v = 0; v < hitbox.length; v++) {
                    var h = hitbox[v]
                    var res = 0
                    res = Trace.Line(entity, h[0], h[1])[1]
                    if (res != 1) {
                        var ny = h[0][2] + 10
                        var nx = h[1][0]
                        var nz = h[1][1]
                        var fny = h[0][2]
                        var fnx = h[1][0]
                        var fnz = h[1][1]
                        vres = Trace.Line(entity, [fnx, fnz, fny], [nx, nz, ny])[1]
                        var start = [x, z, y]
                        var end = [x - mx, z - mz, y - 20]
                        vres1 = Trace.Line(entity, start, end)[1]
                        if (vres == 1 && vres1 == 1) {
                            hittable = true
                            hit = [x + mx * (res), z + mz * (res), y + my * (res)]
                            break;
                        } else {
                            if (vres1 != 1) {
                                pmolotov.push([
                                    [x, z, y], Globals.Tickcount(), Globals.Tickcount() + i, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime')
                                ])
                                hits.push([
                                    [x, z, y], Globals.Tickcount() + i, true, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime')
                                ])
                                return
                            }
                            my = my * -0.45
                            mx = mx * 0.45
                            mz = mz * 0.45
                            break
                        }
                    }
                }
                if (hit.length > 1) {
                    hits.push([
                        [hit[0], hit[1], hit[2]], Globals.Tickcount() + i, true, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime'), Globals.Tickcount()
                    ])
                    break;
                }
                if (i % (isEnabled("Visuals", "Grenade warning line") ? 1 : 2) == 0) {
                    lines.push([
                        [x, z, y],
                        [x + mx, z + mz, y + my], Globals.Tickcount() + i, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime')
                    ])
                }
                x = x + mx
                y = y + my
                z = z + mz
            }
            if (!hittable) {
                hits.push([
                    [x, z, y], Globals.Tickcount() + i, true, Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime'), Globals.Tickcount()
                ])
            }
        }
    }
    const contains = function(arr, contain) {
        for (var i = 0; i < arr.length; i++) {
            var object = arr[i]
            if (object == contain) {
                return true
            }
        }
        return false;
    }
    entities = Entity.GetEntitiesByClassID(9).concat(Entity.GetEntitiesByClassID(114));
    var array = []
    for (var i = 0; i < entities.length; i++) {
        entity = entities[i]
        if (Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_nExplodeEffectTickBegin') == 0) {
            array.push(Entity.GetProp(entity, 'CBaseCSGrenadeProjectile', 'm_flAnimTime'))
        }
    }
    for (var i = 0; i < hits.length; i++) {
        var object = hits[i]
        if (!contains(array, object[3])) {
            hits[i][1] = 0;
        }
    }
    for (var i = 0; i < lines.length; i++) {
        var object = lines[i]
        if (!contains(array, object[3])) {
            lines[i][2] = 0;
        }
    }
    for (var i = 0; i < pmolotov.length; i++) {
        var object = pmolotov[i]
        if (!contains(array, object[3])) {
            pmolotov[i][2] = 1;
            pmolotov[i][1] = -5;
        }
    }
}

function draw_warning(xzy) {
    var font_nade = Render.GetFont("skyline/weaponicons.ttf", 28, false);
    const draw_ind = function(x, y, alpha, str, oof, xzy) {
        Render.Circle(x, y, oof ? (18 + Globals.Tickcount() / 7 % 5) : 20, [155, 155, 155, alpha])
        Render.String(x + 1, y - 18, 1, str, [255, 255, 255, alpha], font_nade);
        var distance = Math.round(vectorDistance(getLocal(), xzy) / 50)
        Render.String(x + 1, y + 7, 1, distance + " m", [255, 255, 255, alpha], small(10));
    }
    var x = Render.WorldToScreen(xzy[0])[0]
    var y = Render.WorldToScreen(xzy[0])[1]
    var str = xzy[2] ? "O" : "j";
    var alpha = (xzy[1] - Globals.Tickcount()) * 2
    if (alpha < 1)
        return;
    size = Render.GetScreenSize()
    if (x < 0 || x > size[0] || y > size[1] || y < 0) {
        if (isEnabled("Visuals", "Grenade warning OOF")) {
            var yaw = (Local.GetViewAngles()[1])
            var myorig = getLocal()
            var orig = xzy[0]
            var x = orig[0] - myorig[0]
            var z = orig[1] - myorig[1]
            var atan = Math.atan2(z, x)
            var deg = atan * (180 / Math.PI);
            deg -= yaw + 90;
            atan = deg / 180 * Math.PI;
            var cos = Math.cos(atan) * -1
            var sin = Math.sin(atan)
            draw_ind(size[0] / 2 + cos * 150, size[1] / 2 + sin * 150, 255, str, true, xzy[0])
        }
    } else {
        draw_ind(x, y, 255, str, false, xzy[0])
    }
}

function grenade_warning_draw() {
    for (var i = 0; i < lines.length; i++) {
        var line = lines[i]
        var alpha = (line[2] - Globals.Tickcount())
        if (alpha > 0) {
            size = Render.GetScreenSize()
            if (Render.WorldToScreen(line[1])[1] > 0 && Render.WorldToScreen(line[0])[1] > 0 && Render.WorldToScreen(line[1])[1] < size[1] && Render.WorldToScreen(line[0])[1] < size[1]) {
                Render.Line(Render.WorldToScreen(line[0])[0], Render.WorldToScreen(line[0])[1], Render.WorldToScreen(line[1])[0], Render.WorldToScreen(line[1])[1], [158, 168, 255, 255])
            }
        }
    }
    for (var i = 0; i < hits.length; i++) {
        var line = hits[i]
        draw_warning(line)
    }
    for (var i = 0; i < pmolotov.length; i++) {
        var molotov = pmolotov[i]
        var xzy = molotov[0]
        var start_timer = molotov[1]
        var end_timer = molotov[2]
        var curr = Globals.Tickcount()
        var max = end_timer - start_timer
        var cur = end_timer - curr
        var proc = cur / max * 300
        if (proc > 0)
            draw_circle_3d(xzy[0], xzy[1], xzy[2], 130, 360, proc, 30, default_color_a, true, [255, 255, 255, 20])
    }
}

function draw_circle_3d(x, y, z, radius, degrees, degrees_outline, start_at, clr, filled, fill_clr) {
    var accuracy = 5;
    var old_x, old_y;
    start_at = start_at + 1
    for (rot = start_at; rot < degrees + start_at + 1; rot += accuracy) {
        rot_r = rot * (Math.PI / 180)
        line_x = radius * Math.cos(rot_r) + x, line_y = radius * Math.sin(rot_r) + y
        var curr = Render.WorldToScreen([line_x, line_y, z]),
            cur = Render.WorldToScreen([x, y, z]);
        if (cur[0] != null && curr[0] != null && old_x != null) {
            if (filled) Render.Polygon([
                [curr[0], curr[1]],
                [old_x, old_y],
                [cur[0], cur[1]]
            ], fill_clr)
        }
        old_x = curr[0], old_y = curr[1];
    }
    for (rot = start_at; rot < degrees_outline + start_at + 1; rot += accuracy) {
        rot_r = rot * (Math.PI / 180)
        line_x = radius * Math.cos(rot_r) + x, line_y = radius * Math.sin(rot_r) + y
        var curr = Render.WorldToScreen([line_x, line_y, z]),
            cur = Render.WorldToScreen([x, y, z]);
        if (cur[0] != null && curr[0] != null && old_x != null) {
            Render.Line(curr[0], curr[1], old_x, old_y, clr)
        }
        old_x = curr[0], old_y = curr[1];
    }
}

function round_start() {
    hits = []
    lines = []
    particles = []
    tracer_lines = []
    pmolotov = []
}

function bullet_impact() {
    player = Event.GetInt("userid");
    player_index = Entity.GetEntityFromUserID(player);
    if (Entity.GetLocalPlayer() == player_index) {
        tracer_lines.push([Entity.GetEyePosition(Entity.GetLocalPlayer()), [Event.GetFloat("x"), Event.GetFloat("y"), Event.GetFloat("z")], Globals.Tickcount() + 90])
    }
}
Cheat.RegisterCallback("bullet_impact", "bullet_impact");
Cheat.RegisterCallback("player_connect_full", "on_player_connect")
Cheat.RegisterCallback("weapon_fire", "swap")
Cheat.RegisterCallback("round_start", "round_start")
Cheat.RegisterCallback("CreateMove", "tick")
Cheat.RegisterCallback("Draw", "draw")
Cheat.RegisterCallback("player_hurt", "hurt")