var iExploitID = 0;
var bDoubleTapped = false;
var bShouldRecharge = false;
var ForceCharge = false;
var iLastShotTime = 0;
var side = 0;
var type,fakeamount,masteryaw,fake = 0;
var screen_width = Math.round(Global.GetScreenSize()[0]);
var local = Entity.GetLocalPlayer();
var target = -1;
var binlib = {};
var iVictim_index, First_pos, Second_pos, Third_pos, Fourth_pos, Fifth_pos, First, Second, Third, Fourth, Five, iDamageCount = iOffsetCount = YOffsetFirst = YOffsetSecond = YOffsetThird = YOffsetFourth = YOffsetFive = loadFont = HitAttack = 0;
var run = false;
var estimate = 0;
var firstBuy = 0;
var alias = [
    ["awp"],
    ["ssg08"],
    ["scar20", "g3sg1"]
]

Cheat.RegisterCallback("CreateMove", "aaLoop");

multiplierOptions = [0,001 ];
function ui()
{
	const time = UI.AddSliderFloat("Effect duration", 0, 2);
	UI.AddColorPicker("Hitlog Color");
	UI.AddLabel("---Anti-Aim---");
    UI.AddCheckbox( "Override Anti-Aim" );
    UI.AddDropdown( "Lagsync:", [ "Off","Lagsync V1" ] );
	UI.AddCheckbox( "SideWitch-Jitter" );
	UI.AddLabel("Invert on shot");
	createDropdown("AA Options on X", ["Invert on Hit", "Flip Offset on Hit", "Randomize Yaw on Hit", "Randomize Yaw on Shot", "Flip Yaw on Shot", "Invert on Shot"], true);
	UI.AddCheckbox("Enable Yaw Flags");
	UI.AddCheckbox("Reset Yaw on Kill");
	UI.AddSliderInt("Default Yaw", -180, 180);
	UI.AddSliderInt("Maximum + Offset", 0, 180);
	UI.AddSliderInt("Maximum - Offset", -180, 0);
	UI.AddLabel("---DoubleTap---");
	UI.AddCheckbox("Doubletap Teleport");
	UI.AddSliderInt("Double tap speed", 0, 1);
	UI.AddLabel("---Credits---");
	UI.AddLabel("Made by Stickz#1337");
}


function roundEnded() {
    run = true;
    estimate = Globals.Curtime()+Convar.GetInt("mp_round_restart_delay");
    firstBuy = 0;
}

function purchase(index) {
    alias[index].forEach(function(v) { Cheat.ExecuteCommand("buy "+v); })
    run = false;
}

function onDraw() {
    run && Globals.Curtime()+(Local.Latency()/1000) >= estimate && purchase(UI.GetValue.apply(this, dropdown));
}

function purchased() {
    if (firstBuy == 0) firstBuy = Globals.Curtime()-estimate;
    if (!Entity.GetEntityFromUserID(Event.GetInt("userid")) || firstBuy == -1) return;

    Cheat.Print("The first item of the round was purchased at " + firstBuy + "s, you purchased at " + (Globals.Curtime()-estimate) + "s.\n");
    firstBuy = -1;
}

var dropdown = UI.AddDropdown("Fastest Autobuy", ["AWP", "Scout", "Auto"]);

Cheat.RegisterCallback("round_end", "roundEnded");
Cheat.RegisterCallback("Draw", "onDraw");
Cheat.RegisterCallback("item_purchase", "purchased");



const first_screen_pos = [], second_screen_pos = [], third_screen_pos = [], fourth_screen_pos = [], fifth_screen_pos = [];


function EVENT_PLAYER_HURT()
{
    
    iAttacker = Event.GetInt("attacker"); iAttacker_index = Entity.GetEntityFromUserID(iAttacker);
   
    
    iVictim = Event.GetInt("userid"); iVictim_index = Entity.GetEntityFromUserID(iVictim);  
   
    if(Entity.GetLocalPlayer() == iVictim_index && Entity.GetLocalPlayer() !== iAttacker_index)    return;
   
    
    if(Entity.GetLocalPlayer() == iAttacker_index)
    {
        
        HitAttack = 1;
       
        
        if(iDamageCount == 5) iDamageCount = 0; if(iOffsetCount == 5) iOffsetCount = 0;
       
        
        iDamageCount+=1;
       
        
        iOffsetCount+=1;        
       
        
        if(iDamageCount == 1)    {    First = Event.GetInt("dmg_health");    First_pos = Entity.GetRenderOrigin(iVictim_index);    }  
        if(iDamageCount == 2)    {    Second = Event.GetInt("dmg_health");    Second_pos = Entity.GetRenderOrigin(iVictim_index);    }              
        if(iDamageCount == 3)    {    Third = Event.GetInt("dmg_health");    Third_pos = Entity.GetRenderOrigin(iVictim_index);    }      
        if(iDamageCount == 4)    {    Fourth = Event.GetInt("dmg_health");    Fourth_pos = Entity.GetRenderOrigin(iVictim_index);    }      
        if(iDamageCount == 5)    {    Five = Event.GetInt("dmg_health");    Fifth_pos = Entity.GetRenderOrigin(iVictim_index);    }

        //Setup offsets
        if(iOffsetCount == 1)    YOffsetFirst = 255; if(iOffsetCount == 2)    YOffsetSecond = 255; if(iOffsetCount == 3)    YOffsetThird = 255; if(iOffsetCount == 4)    YOffsetFourth = 255; if(iOffsetCount == 5)    YOffsetFive = 255;              
    }      
}

function HUD_REDRAW()
{
    
    if(loadFont == 0)
    {
        
        fontSM2 = Render.AddFont("Roboto Medium", 18, 100);
        loadFont = 1;
    }
   
   
    if(!HitAttack || !getCustomValue('Quake Damage Numbers'))    return;

    
    if(Entity.IsValid(iVictim_index))
    {
        
        if(YOffsetFirst > 1)    YOffsetFirst--; if(YOffsetSecond > 1)    YOffsetSecond-=2; if(YOffsetThird > 1)    YOffsetThird-=3; if(YOffsetFourth > 1)    YOffsetFourth-=2; if(YOffsetFive > 1)    YOffsetFive--;  
   
        
        if(iDamageCount == 1)    first_screen_pos = Render.WorldToScreen(First_pos);    if(iDamageCount == 2)    second_screen_pos = Render.WorldToScreen(Second_pos);
        if(iDamageCount == 3)    third_screen_pos = Render.WorldToScreen(Third_pos);    if(iDamageCount == 4)    fourth_screen_pos = Render.WorldToScreen(Fourth_pos);
        if(iDamageCount == 5)    fifth_screen_pos = Render.WorldToScreen(Fifth_pos);
           
        
        Render.StringCustom(first_screen_pos[0]-15, first_screen_pos[1]-50+YOffsetFirst-255, 1, "" + First, [ 255, 255, 255, YOffsetFirst ], fontSM2);
        Render.StringCustom(second_screen_pos[0]+15, second_screen_pos [1]-50+YOffsetSecond-255, 1, "" + Second, [ 255, 255, 255, YOffsetSecond ], fontSM2);
        Render.StringCustom(third_screen_pos[0]-25, third_screen_pos[1]-50+YOffsetThird-255, 1, "" + Third, [ 255, 255, 255, YOffsetThird ], fontSM2);
        Render.StringCustom(fourth_screen_pos[0]+25, fourth_screen_pos[1]-50+YOffsetFourth-255, 1, "" + Fourth, [ 255, 255, 255, YOffsetFourth ], fontSM2);
        Render.StringCustom(fifth_screen_pos[0]-10, fifth_screen_pos[1]-50+YOffsetFive-255, 1, "" + Five, [ 255, 255, 255, YOffsetFive ], fontSM2);
    }      
}  

function getCustomValue(name)
{
    var value = UI.GetValue("MISC", "JAVASCRIPT", "Script items", name);
    return value;
}

function Main()
{
    Global.RegisterCallback("Draw", "HUD_REDRAW");
    Global.RegisterCallback("player_hurt", "EVENT_PLAYER_HURT");
    UI.AddCheckbox('Quake Damage Numbers');
}

Main();

function damage() {
    if(!Entity.IsLocalPlayer(Entity.GetEntityFromUserID(Event.GetInt("userid"))) || !UI.GetValue("Script items", "Enable Yaw Flags")) return;

    opts = fetchDropdown("AA Options on X");
    if (!Entity.IsAlive(local)) return;

    if(opts.indexOf("Invert on Hit") != -1)
        UI.ToggleHotkey("Anti-Aim", "Fake angles", "Inverter");

    if(opts.indexOf("Flip Offset on Hit") != -1)
        UI.SetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset", -UI.GetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset"));
    
    if(opts.indexOf("Randomize Yaw on Hit") != -1)
        randomizeYaw();
}

function shot() {
    if(!Entity.IsLocalPlayer(Entity.GetEntityFromUserID(Event.GetInt("userid"))) || !UI.GetValue("Script items", "Enable Yaw Flags")) return;

    opts = fetchDropdown("AA Options on X");
    if(opts.indexOf("Invert on Shot") != -1)
        UI.ToggleHotkey("Anti-Aim", "Fake angles", "Inverter");

    if(opts.indexOf("Flip Offset on Shot") != -1)
        UI.SetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset", -UI.GetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset"));
    
    if(opts.indexOf("Randomize Yaw on Shot") != -1)
        randomizeYaw();   


}

function randomizeYaw() {
    np = Math.random() * 100;
    rand = 0;

    if (np <= 50) {
        rand = (Math.random() * UI.GetValue("Scipt items", "Maximum - Offset"));
    } else
        rand = Math.random() * UI.GetValue("Scipt items", "Maximum + Offset");

    UI.SetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset", rand);
}

function set_target() {
    if(!UI.GetValue("Enable Yaw Flags")) return;

    target = Event.GetInt("target_index");
}

function reset_yaw() {
    if(!UI.GetValue("Script items", "Enable Yaw Flags") || !UI.GetValue("Script items", "Reset Yaw on Kill")) return;

    if(!Entity.IsAlive(target) && Entity.IsValid(target)) {
        UI.SetValue("Anti-Aim", "Rage Anti-Aim", "Yaw offset", UI.GetValue("Script items", "Default Yaw"));
        target = -1;
    }
}


function dictLength(dict) {
    var count = 0;
    for (_ in dict) {
        count++;
    }
    return count;
}

function createDropdown(name, values, multi) {
    UI[multi ? "AddMultiDropdown" : "AddDropdown"](name, values);
  
    binlib[name] = {"multi": multi, "values": {}};

    multi && values.reverse();

    var i = 0; for (value in values) {
        var index = multi ? (1 << (values.length-(i+1))) : i;
        binlib[name].values[index] = values[value];
        i++;
    }
}

function fetchDropdown(name) {
    var selection = (name ? [] : {})
    var bin = UI.GetValue("Misc", name);

    !name && function() {for (dropdown in binlib) selection[dropdown] = fetchDropdown(dropdown) }();

    if (name) {
        !binlib[name].multi && bin == 0 && selection.push(binlib[name].values[0]) && function() { return selection; }();
        for (var i = dictLength(binlib[name].values)-1; i >= 0; i--) {
            if (!binlib[name].multi && i == 0) continue;

            var index = binlib[name].multi ? (1 << i) : i;
            if (bin-index >= 0) {
                bin -= (index);
                selection.push(binlib[name].values[index]);
            }
        }
    }

    return selection;
}

Cheat.RegisterCallback("player_hurt", "damage");
Cheat.RegisterCallback("weapon_fire", "shot");
Cheat.RegisterCallback("ragebot_fire", "set_target");
Cheat.RegisterCallback("Draw", "reset_yaw");

function HSVtoRGB(h, s, v)
{
    var r, g, b, i, f, p, q, t;

    i = Math.floor(h * 6);
    f = h * 6 - i;
    p = v * (1 - s);
    q = v * (1 - f * s);
    t = v * (1 - (1 - f) * s);

    switch (i % 6)
    {
        case 0: r = v, g = t, b = p; break;
        case 1: r = q, g = v, b = p; break;
        case 2: r = p, g = v, b = t; break;
        case 3: r = p, g = q, b = v; break;
        case 4: r = t, g = p, b = v; break;
        case 5: r = v, g = p, b = q; break;
    }

    return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
}

function onDrawEvent()
{
    var colors = HSVtoRGB(Global.Realtime() * UI.GetValue("MISC", "JAVASCRIPT", "Script Items", "Rainbow Line Speed"), 1, 1);

    Render.GradientRect(0, 0, screen_width/2, 4, 1, [colors.g, colors.b, colors.r, 255], [colors.r, colors.g, colors.b, 255]);
    Render.GradientRect(screen_width/2, 0, screen_width/2, 4, 1, [colors.r, colors.g, colors.b, 255], [colors.b, colors.r, colors.g, 255]);
}

Global.RegisterCallback("Draw", "onDrawEvent");
UI.AddSliderFloat("Rainbow Line Speed", 0.01, 1.0);
UI.SetValue("MISC", "JAVASCRIPT", "Script Items", "Rainbow Line Speed", 0.1);

function clamp(v, min, max)
{
    return Math.max(Math.min(v, max), min);
}

function get(element)
{
    return UI.GetValue("Misc", "JAVASCRIPT", "Script items", element);
}


function render_effect()
{
    if (alpha === 0)
        return;

    const inc_alpha = ((1 / get("Effect duration")) * Global.Frametime()) * 255
    const inc_size = ((1 / get("Effect duration")) * Global.Frametime()) * 360

    alpha = clamp(alpha - inc_alpha, 0, 255);
    size = clamp(size - inc_size, 0, 360);

    const x = Global.GetScreenSize()[0], y = Global.GetScreenSize()[1];

    Render.GradientRect(0, 0, x, size, 0, [128, 195, 255, alpha], [128, 195, 255, 0]);
    Render.GradientRect(0, y - size, x, size, 0, [128, 195, 255, 0], [128, 195, 255, alpha]);
    Render.GradientRect(x - size, 0, size, y, 1, [128, 195, 255, 0], [128, 195, 255, alpha]);
    Render.GradientRect(0, 0, size, y, 1, [128, 195, 255, alpha], [128, 195, 255, 0]);
}

function on_death()
{
    const attacker = Entity.GetEntityFromUserID(Event.GetInt("attacker"));
    const userid = Entity.GetEntityFromUserID(Event.GetInt("userid"));
    const player = Entity.GetLocalPlayer();

    if (attacker === player && userid != player)
    {
        alpha = 255;
        size = 360;
    }
}

Global.RegisterCallback("player_death", "on_death");
Global.RegisterCallback("Draw", "render_effect");



function hsv_to_rgb(h, s, v)
{
    var r, g, b, i, f, p, q, t;
    return { r: Math.round(r * 255), g: Math.round(g * 255), b: Math.round(b * 255) };
}
function getCustomValue(xy) {
var value = UI.GetValue("MISC", "JAVASCRIPT", "Script items", xy);
return value;}
var position = {
  x1: 0,
  y1: 0
}

function draw_fatality_rect(x, y, width, height)
{
        var rgbcolor = hsv_to_rgb(Global.Realtime() * UI.GetValue("MISC", "JAVASCRIPT", "Script Items", "Gradient Speed"), 1, 1);

}

function draw_fatality_rect2(x2, y2, width2, height2)
{
        var rgbcolor = hsv_to_rgb(Global.Realtime() * UI.GetValue("MISC", "JAVASCRIPT", "Script Items", "Gradient Speed"), 1, 1);

      Render.Rect( x2 + 45, y2 + 2, width2 + 60, height2 + -10, [ rgbcolor.g, rgbcolor.b, rgbcolor.r, 200 ] );
     Render.FilledRect( x2 + 46, y2 + 3, width2 + 58, height2 + -10, [ 55, 55, 55, 200 ] );
     Render.FilledRect( x2 + 50, y2 + 7, width2 - -50, height2 - 19, [ 30, 30, 30, 200 ] ); // black
      Render.Rect( x2 + 50, y2 + 6, width2 - -50, height2 + -17, [ rgbcolor.g, rgbcolor.b, rgbcolor.r, 200 ] );
}

function draw_fatality_rect3(x3, y3, width3, height3)
{

}

function draw_gs_watermark()
{
  var rgbcolor = hsv_to_rgb(Global.Realtime() * UI.GetValue("MISC", "JAVASCRIPT", "Script Items", "Gradient Speed"), 1, 1);
  var fps1 = 1 / Global.Frametime()
  var fps = Math.floor(fps1)
  var watermark_name = Entity.GetName(Entity.GetLocalPlayer( ));
  var today = new Date();
  var datetime = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds();
    x1 = getCustomValue("X");
    y1 = getCustomValue("Y");





    draw_fatality_rect(x1, y1, 40, 35);
    draw_fatality_rect2(x1 - 150, y1, 140, 35);
    draw_fatality_rect3(x1 - 300, y1, 140, 35);
    Render.String( x1 + -64, y1 + 10, 0, "Js", [ 166, 243, 65, 255], 8 );
    Render.String( x1 + -96, y1 + 10, 0, "Dark", [ 255, 255, 255, 255], 8 );
    Render.String( x1 + -28, y1 + 10, 0, "|", [ 255, 255, 255, 255], 8 );
    Render.String( x1 - 20, y1 + 10, 0, "" + fps, [ 166, 243, 65, 255], 8 );
    Render.String( x1 - -3, y1 + 10, 0, "fps |", [ 255, 255, 255, 255], 8 );
    Render.String( x1 + 28, y1 + 10, 0, " " + datetime, [ 255, 255, 255, 255 ], 8 );

}

function main()
{
        var screensize = Global.GetScreenSize();
        UI.AddSliderInt("X", 0, screensize[0]);
        UI.AddSliderInt("Y", 0, screensize[0]);
}
main()

Global.RegisterCallback("Draw", "draw_gs_watermark")
 
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 _TBC_CREATE_MOVE() {
    var is_charged = Exploit.GetCharge()
    var reserve = UI.GetValue("Misc", "JAVASCRIPT", "Script items", "Double tap speed(lower is faster)")

    Exploit[(is_charged != 1 ? "Enable" : "Disable") + "Recharge"]()

    if (can_shift_shot(14) && is_charged != 1) {
        Exploit.DisableRecharge();
        Exploit.Recharge()
    }

    Exploit.OverrideTolerance(reserve);
    Exploit.OverrideShift(14-reserve);
}

function _TBC_UNLOAD() {
    Exploit.EnableRecharge();
}

Cheat.RegisterCallback("CreateMove", "_TBC_CREATE_MOVE");
Cheat.RegisterCallback("Unload", "_TBC_UNLOAD");

function aaLoop() {
    AntiAim.SetOverride(1);

        AntiAim.SetFakeOffset(getRandomIntInclusive( 5969, -5969));
        AntiAim.SetRealOffset(getRandomIntInclusive( -3425, 3425))
}



function getRandomIntInclusive(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (min * max - 0,0003)) + min;
  }

function on_ragebot_fire()
{
    ragebot_target_exploit = Event.GetInt("exploit");
    if (UI.GetValue("Misc", "JAVASCRIPT", "Script items", "Doubletap Teleport"))
    {
        (ragebot_target_exploit == 2) ? UI.ToggleHotkey("Rage", "GENERAL", "Exploits", "Doubletap") : UI.ToggleHotkey("Rage", "GENERAL", "Exploits", "Doubletap");
    }   
}

Global.RegisterCallback("ragebot_fire", "on_ragebot_fire");

function yawhandles(type,fakeamount,masteryaw,fake)
{
    var localplayer_index = Entity.GetLocalPlayer( );
    var velocity = Entity.GetProp( localplayer_index, "CBasePlayer", "m_vecVelocity[0]" );
    var currentspeed = Math.round(Math.sqrt(Math.pow(velocity[0],2)+ Math.pow(velocity[1],2)));

       if(currentspeed <= 0 && type == 1 )//standing
        {
            
            AntiAim.SetLBYOffset(fakeamount);
            AntiAim.SetRealOffset(fake);
            AntiAim.SetFakeOffset(masteryaw);
        }
    else if(currentspeed > 0 && type == 2 )
        {
            Cheat.Print(currentspeed + "\n");
            AntiAim.SetLBYOffset(fakeamount);
            AntiAim.SetRealOffset(fake);
            AntiAim.SetFakeOffset(masteryaw);
        }
    
    
}

function getRndInteger(min, max) {
  return Math.ceil(Math.random() * (max - min) ) + min;
}

function Initialize()
{ 
    
    var lagsyncmode = UI.GetString("MISC", "JAVASCRIPT", "Script items", "Lagsync mode:");
    
    if(UI.GetValue( "MISC", "JAVASCRIPT", "Script items", "Override AA" ))
        {
            AntiAim.SetOverride(1);
            
            //side = 0.55 * Math.sin((Globals.Realtime()-(-1.9))/0.1) + 0.5;
            side = getRndInteger(0,4);
            Cheat.Print(side + "\n");
           
            if(lagsyncmode == "Lagsync V1")
                {
                    if(side  == 4)
                        {
                            Cheat.Print("side" + "\n");
                            type = 2;
                            masteryaw = 25;
                            fakeamount = -70;
                            fake = 70;
                            
                            yawhandles(type,fakeamount,masteryaw,fake);
                            
                            type = 1;
                            masteryaw = 25;
                            fakeamount = -70;
                            fake = 70;
                            
                           yawhandles(type,fakeamount,masteryaw,fake);
                            
                        }
                        else if (side  == 1)
                        {
                            Cheat.Print("!side" + "\n");
                            type = 1;
                            masteryaw = -15;
                            fakeamount = -65;
                            fake = 65;
                            
                            yawhandles(type,fakeamount,masteryaw,fake);
                            
                            type = 2;
                            masteryaw = -15;
                            fakeamount = -65;
                            fake = 65;
                            
                           yawhandles(type,fakeamount,masteryaw,fake);
                            
                    
                        }
                    
                }
            
            
        }
    else
        AntiAim.SetOverride(0);
    
}


function Renders()
{
    
}

ui();
Cheat.RegisterCallback("CreateMove", "Initialize");

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(14) * (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 _TBC_CREATE_MOVE() {
    var is_charged = Exploit.GetCharge()
   
    Exploit[(is_charged != 1 ? "Enable" : "Disable") + "Recharge"](1)

    if (can_shift_shot(14) && is_charged != 1) {
        Exploit.DisableRecharge();
        Exploit.Recharge(1)
    }
}

function _TBC_UNLOAD() {
    Exploit.EnableRecharge(1);
}
function on_createmove()
{
    Exploit.OverrideShift(14)
    Exploit.OverrideTolerance(1)
}
Cheat.RegisterCallback("CreateMove", "_TBC_CREATE_MOVE");
Cheat.RegisterCallback("Unload", "_TBC_UNLOAD");
Cheat.RegisterCallback("CreateMove", "on_createmove")


const hitgroup = ['head', 'neck', 'pelvis', 'body', 'stomach', 'chest', 'upper chest', 'left thigh', 'right thigh', 'left calf', 'right calf', 'left foot', 'right foot', 'left hand', 'right hand', 'left upper arm', 'left forearm', 'right upper arm', 'right forearm'];

const activeLogs = [];

const ragebotTarget = {};



var color = UI.GetColor("MISC", "JAVASCRIPT", "Script Items", "Hitlog Color");
if (color[0] === 0 && color[1] === 0 && color[2] === 0 && color[3] === 0)
    UI.SetColor("MISC", "JAVASCRIPT", "Script Items", "Hitlog Color", [32, 213, 225, 255]);




function getMultiColorTextSize(lines) {
    var w = 0;
    for (var x = 0; x < lines.length; x++) {
        w += Render.TextSize(lines[x][1], 8)[0];
    }
    return w;
}


function drawMultiColorText(x, y, lines) {
    var x_pad = 0;
    for (var i = 0; i < lines.length; i++) {
        const line = lines[i];
        const text = line[1];
        var color = line[0];
        if (typeof line[0] == "number") {
            color = UI.GetColor("MISC", "JAVASCRIPT", "Script Items", "Hitlog Color");
        }
        Render.String(x + x_pad, y, 0, text, color, 8);
        const w = Render.TextSize(text, 8)[0];
        x_pad += w;
    }
}



function showLog(count, layer) {
    const text = layer.text;
    const w = getMultiColorTextSize(text);
    const expiry = Global.Realtime() < layer.delay;
    const y = 26 + (26 * (count - 1));
    const h = 6;
    const logW = (w < 0) ? 0 : (w + 50);
    const speed = 10;
    const layerSize = 4;

    layer.firstLayer = expiry ? Math.min(layer.firstLayer + logW * 0.025, logW + layerSize) : Math.max(layer.firstLayer - speed, 0);
    layer.secondLayer = expiry ? Math.min(layer.secondLayer + logW * 0.025, logW) : Math.max(layer.secondLayer - 1 * speed, 0);
    var color = UI.GetColor("MISC", "JAVASCRIPT", "Script Items", "Hitlog Color");
    Render.FilledRect(layer.firstLayer - layer.firstLayer, y, layer.firstLayer, h + 20, color);
    Render.FilledRect(layer.secondLayer - layer.secondLayer, y, layer.secondLayer, h + 20, [5, 21, 39, 255]);

    drawMultiColorText(layer.secondLayer - logW + 5, y + 2 + 6, text);
    activeLogs[count] = layer;
    if (layer.secondLayer === 0) {
        activeLogs.splice(count, 1);
    }
}

function onDraw() {
    for (var x = 0; x < activeLogs.length; x++) {
        showLog(x, activeLogs[x]);
    }
}

function onRagebotFire() {
    ragebotTarget[Entity.GetName(Event.GetInt("target_index"))] = {
        hitgroup: hitgroup[Event.GetInt("hitbox")],
        hc: Event.GetInt("hitchance"),
        safepoint: Event.GetInt("safepoint"),
        exploit: Event.GetInt("exploit")
    }
}

function onPlayerHurt() {
    const attacker = Entity.GetEntityFromUserID(Event.GetInt("attacker"));
    const victim = Entity.GetEntityFromUserID(Event.GetInt("userid"));
    const victimName = Entity.GetName(victim);
    if (attacker === Entity.GetLocalPlayer() && victim !== Entity.GetLocalPlayer()) {
        const target = ragebotTarget[victimName];
        if (target != null) {
            const hitMessage = [
                [[255, 255, 255, 255], " You did "],
                [[255, 255, 255, 255], Event.GetInt("dmg_health").toString()],
                [[255, 255, 255, 255], " damage"],
                [[255, 255, 255, 255], " to "],
                [[255, 255, 255, 255], victimName.substring(0, 12)],
                [[255, 255, 255, 255], " in "],
                [[255, 255, 255, 255], target.hitgroup],
                [[255, 255, 255, 255], "  "],
            ];
            activeLogs.push({
                    text: hitMessage,
                    delay: Global.Realtime() + 7,
                    firstLayer: 0,
                    secondLayer: 0
                }
            );
        }
    }
}



Global.RegisterCallback("Draw", "onDraw");
Global.RegisterCallback("ragebot_fire", "onRagebotFire");
Global.RegisterCallback("player_hurt", "onPlayerHurt");