#ifndef ESP_H
#define ESP_H

#define kWidth  [UIScreen mainScreen].bounds.size.width
#define kHeight [UIScreen mainScreen].bounds.size.height
#define RAD2DEG(x) ((float)(x) * (float)(180.f / IM_PI))
#define DEG2RAD(x) ((float)(x) * (float)(IM_PI / 180.f))
#define kWidth  [UIScreen mainScreen].bounds.size.width
#define kHeight [UIScreen mainScreen].bounds.size.height
ImU32 color = IM_COL32(255, 255, 255, 150);

// Tối ưu hóa operator overloading bằng cách sử dụng initializer list
static inline ImVec2 operator*(const ImVec2& lhs, float rhs) { return {lhs.x * rhs, lhs.y * rhs}; }
static inline ImVec2 operator/(const ImVec2& lhs, float rhs) { return {lhs.x / rhs, lhs.y / rhs}; }
static inline ImVec2 operator+(const ImVec2& lhs, float rhs) { return {lhs.x + rhs, lhs.y + rhs}; }
static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return {lhs.x + rhs.x, lhs.y + rhs.y}; }
static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return {lhs.x - rhs.x, lhs.y - rhs.y}; }
static inline ImVec2 operator-(const ImVec2& lhs, float rhs) { return {lhs.x - rhs, lhs.y - rhs}; }
static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return {lhs.x * rhs.x, lhs.y * rhs.y}; }
static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return {lhs.x / rhs.x, lhs.y / rhs.y}; }
static inline ImVec2& operator*=(ImVec2& lhs, float rhs) {
    lhs.x *= rhs;
    lhs.y *= rhs;
    return lhs;
}
static inline ImVec2& operator/=(ImVec2& lhs, float rhs) {
    lhs.x /= rhs;
    lhs.y /= rhs;
    return lhs;
}
static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) {
    lhs.x += rhs.x;
    lhs.y += rhs.y;
    return lhs;
}
static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) {
    lhs.x -= rhs.x;
    lhs.y -= rhs.y;
    return lhs;
}
static inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) {
    lhs.x *= rhs.x;
    lhs.y *= rhs.y;
    return lhs;
}
static inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) {
    lhs.x /= rhs.x;
    lhs.y /= rhs.y;
    return lhs;
}
static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return {lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w}; }
static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return {lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w}; }
static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return {lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w}; }

template <typename T>
inline float lerp(float a, float b, float f) { 
    return std::clamp<float>(a + f * (b - a), a > b ? b : a, a > b ? a : b); 
}


class Vvector3 {
public:
    float X;
    float Y;
    float Z;
    Vvector3() : X(0), Y(0), Z(0) {}
    Vvector3(float x1, float y1, float z1) : X(x1), Y(y1), Z(z1) {}
    Vvector3(const Vvector3 &v);
    ~Vvector3();
};
Vvector3::Vvector3(const Vvector3 &v) : X(v.X), Y(v.Y), Z(v.Z) {}
Vvector3::~Vvector3() {}

static void Transform_INTERNAL_SetPosition(void *player, Vvector3 inn) {
   void (*_Transform_INTERNAL_SetPosition)(void *transform, Vvector3 in) = (void (*)(void *, Vvector3))getRealOffset(0x105F3D540);
    _Transform_INTERNAL_SetPosition(player, inn);
}

inline float lerp(float a, float b, float f) { return clamp(a + f * (b - a), std::min(a, b), std::max(a, b)); }

inline ImColor collerp(ImColor a, ImColor b, float f) { return {a.Value.x + f * (b.Value.x - a.Value.x), a.Value.y + f * (b.Value.y - a.Value.y), a.Value.z + f * (b.Value.z - a.Value.z), a.Value.w + f * (b.Value.w - a.Value.w)}; }
    static int circle_size = 0;
float ESPRounding;
static bool ESPEnable = false, ESPLine = false, ESPBox = false, ESP2DBox = false, ESP3DBox = false, ESP3DBox2 = false, Fov = false;
bool bone = false;
static bool ESPCount = false, ESPCount2 = false,ESPArrow = false, ESPArrow2 = false, ESPHealth = false, ESPHealth2 = false, ESPName = false;

static bool ESPOutline = false, ESPDistance = false, ESPDistance2 = false, RS = false;
bool LINEEEE = false, BOXXXX = false;
static int sliderDistanceValue = 150;
static int AimbotFOV = 100; 
static int AimDis = 150;
int AimCheck = 0;
int AimType = 0;
int AimWhen = 1;
bool Aimbot;
bool Enable = true;
bool Aimkill = false;
bool isAiming = false;
bool Telekill = false;
int style_idx = 0;
int aim_target = 0; 
int aim_location = 0; 
int aim_trigger = 0; 
float colorEsp[3] = {255, 255, 255}; 
void* (*get_main)();
void* (*get_transform)(void*);
Vector3 (*WorldToViewpoint)(void*, Vector3, int);
Vector3 (*get_position)(void*);

static void* Camera_main() {
    void* (*_Camera_main)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105EF6D08"));  
    return _Camera_main(nullptr);
}

static Vector3 get_AttackableCenterWS(void* player) {
    Vector3 (*_get_AttackableCenterWS)(void*) = (Vector3 (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105257F30"));
    return _get_AttackableCenterWS(player);
}

void* PlayerWeaponOnHand(void* Player){
    void*(*WeaponOnHand)(void*) = (void*(*)(void*))getRealOffset(ENCRYPTOFFSET("0x10525853C"));
    return WeaponOnHand(Player);
}

Vector3 CameraPosition(void*Player){ 
	Vector3 Position = Vector3::Zero();
    void(*PositionInjected)(void*,Vector3*) = (void(*)(void*,Vector3*))getRealOffset(ENCRYPTOFFSET("0x105F3D49C"));
    PositionInjected(*(void**)((uintptr_t) Player + 0x1C8),&Position);
    return Position;
}

void* PlayerTakeDamage(void* Player,void* DamageInfo,void* DamagerWeaponDynamicInfo,void* CheckParams,uint DamagerVehicleID){
    void*(*TakeDamage)(void*,void*,void*,void*,uint) = (void*(*)(void*,void*,void*,void*,uint))getRealOffset(ENCRYPTOFFSET("0x1052A6A98"));
    return TakeDamage(Player,DamageInfo,DamagerWeaponDynamicInfo,CheckParams,DamagerVehicleID);
}

void PlayerNetworkStartWholeBodyFiring(void* Player,void* WeaponOnHand){
    void(*StartWholeBodyFiring)(void*,void*) = (void(*)(void*,void*))getRealOffset(ENCRYPTOFFSET("0x1053AE7C8"));
    return StartWholeBodyFiring(Player,WeaponOnHand);
}

void PlayerNetworkStopFire(void* Player,void* WeaponOnHand){
    void(*StopFire)(void*,void*) = (void(*)(void*,void*))getRealOffset(ENCRYPTOFFSET("0x105395784"));
    return StopFire(Player,WeaponOnHand);
}

void* GameFacadeCurrentLocalPlayer(){
    void*(*CurrentLocalPlayer) (void*) = (void*(*)(void*))getRealOffset(ENCRYPTOFFSET("0x1024264E0"));
    return CurrentLocalPlayer(NULL);
}

Vector3 PlayerHeadPosition(void* Player){
    void*(*HeadPosition)(void*) = (void*(*)(void*))getRealOffset(ENCRYPTOFFSET("0x1052BECB8"));
	Vector3 Position = Vector3::Zero();
    void(*PositionInjected)(void*,Vector3*) = (void(*)(void*,Vector3*))getRealOffset(ENCRYPTOFFSET("0x105F3D49C"));
    PositionInjected(HeadPosition(Player),&Position);
    return Position;
}

static bool setname = true;

static void *Current_Local_Player() {
    void *(*_Local_Player)(void *players) = (void *(*)(void *))getRealOffset(0x1024264E0);  
    return _Local_Player(NULL);
}

static monoString *U3DStr(const char *str) {
    monoString *(*String_CreateString)(void *_this, const char *str) = (monoString * (*)(void *, const char *))getRealOffset(0x1060775D0);  
    return String_CreateString(NULL, str);
}

static void spofNick(void *players) {
void (*_spof_nick)(void *player, monoString *nick) = (void (*)(void *, monoString *))getRealOffset(0x105258CE0);    
_spof_nick(players, U3DStr(ENCRYPTHEX("[FF33CC]TELEGRAM [7FFF00]BÁN HACK [CC34BA]@canhioscrack")));
}

ImVec2 world2screen_i(Vector3 pos) {
    auto cam = Camera_main();
    if (!cam) return {0, 0};

    Vector3 worldPoint = WorldToViewpoint(cam, pos, 2);

    int ScreenWidth = ImGui::GetIO().DisplaySize.x;
    int ScreenHeight = ImGui::GetIO().DisplaySize.y;

    return {ScreenWidth * worldPoint.x, ScreenHeight - worldPoint.y * ScreenHeight};
}

ImVec2 world2screen_c(Vector3 pos, bool& checker) {
    auto cam = Camera_main();
    if (!cam) return {0, 0};

    Vector3 worldPoint = WorldToViewpoint(cam, pos, 2);

    int ScreenWidth = ImGui::GetIO().DisplaySize.x;
    int ScreenHeight = ImGui::GetIO().DisplaySize.y;

    Vector3 location = {ScreenWidth * worldPoint.x, ScreenHeight - worldPoint.y * ScreenHeight, worldPoint.z};

    checker = location.z > 1;
    return {location.x, location.y};
}

void *(*_GetHeadPositions)(void *);
 void *GetHeadPositions(void *player) {
    if (_GetHeadPositions && player) {
        return _GetHeadPositions(player);
    }
    return nullptr; 
}

void *(*_newHipMods)(void *player);
void *HipTF(void *player) {
    if (_newHipMods) {
        return _newHipMods(player);
    }
    return nullptr;  
}


void *(*_GetLeftAnkleTF)(void *player);
void *(*_GetRightAnkleTF)(void *player);
void *(*_GetLeftToeTF)(void *player);
void *(*_GetRightToeTF)(void *player);
void *(*_getLeftHandTF)(void *player);
void *(*_getRightHandTF)(void *player);
void *(*_getLeftForeArmTF)(void *player);
void *(*_getRightForeArmTF)(void *player);

void *GetLeftAnkleTF(void *player) {
    if (_GetLeftAnkleTF) {
        return _GetLeftAnkleTF(player);
    }
    return nullptr; 
}

void *GetRightAnkleTF(void *player) {
    if (_GetRightAnkleTF) {
        return _GetRightAnkleTF(player);
    }
    return nullptr;
}

void *GetLeftToeTF(void *player) {
    if (_GetLeftToeTF) {
        return _GetLeftToeTF(player);
    }
    return nullptr;
}

void *GetRightToeTF(void *player) {
    if (_GetRightToeTF) {
        return _GetRightToeTF(player);
    }
    return nullptr;
}

void *getLeftHandTF(void *player) {
    if (_getLeftHandTF) {
        return _getLeftHandTF(player);
    }
    return nullptr;
}

void *getRightHandTF(void *player) {
    if (_getRightHandTF) {
        return _getRightHandTF(player);
    }
    return nullptr;
}

void *getLeftForeArmTF(void *player) {
    if (_getLeftForeArmTF) {
        return _getLeftForeArmTF(player);
    }
    return nullptr;
}

void *getRightForeArmTF(void *player) {
    if (_getRightForeArmTF) {
        return _getRightForeArmTF(player);
    }
    return nullptr;
}



 Vector3 GetHeadPosition(void* player) {
    return get_position(GetHeadPositions(player));
}

Vector3 GetHipPosition(void* player) {
    return get_position(HipTF(player));
}

Vector3 GetNeckPosition(void* player) {
    Vector3 headPosition = GetHeadPosition(player);
    Vector3 neckOffset = Vector3(0, -0.2f, 0); 
    return headPosition + neckOffset;
}


 Vector3 GetLeftAnkleTFs(void* player) {
    return get_position(GetLeftAnkleTF(player));
}

 Vector3 GetRightAnkleTFs(void* player) {
    return get_position(GetRightAnkleTF(player));
}

 Vector3 GetLeftToeTFs(void* player) {
    return get_position(GetLeftToeTF(player));
}

 Vector3 GetRightToeTFs(void* player) {
    return get_position(GetRightToeTF(player));
}

 Vector3 getLeftHandTFs(void* player) {
    return get_position(getLeftHandTF(player));
}

 Vector3 getRightHandTFs(void* player) {
    return get_position(getRightHandTF(player));
}

 Vector3 getLeftForeArmTFs(void* player) {
    return get_position(getLeftForeArmTF(player));
}

 Vector3 getRightForeArmTFs(void* player) {
    return get_position(getRightForeArmTF(player));
}

int (*get_CurHP)(void* player);
bool get_isLiving(void* player) {
    return get_CurHP(player) > 0; 
}
/*
bool (*Team)(void*);
bool IsTeammate(void* player) {
    return Team && player ? Team(player) : false;
}
*/
bool (*Team) (void*);
bool IsTeammate(void *player) {
    if (Team && player) {
        
        return Team(player);
    }
    return false;
}

bool (*Local)(void*);
bool IsLocalPlayer(void* player) {
    return Local && player ? Local(player) : false;
}

int (*get_MaxHP)(void* player);

monoString* get_Nickname(void* player) {
    monoString* (*nickname)(void*) = (monoString* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105258C80")); 
    return nickname(player);  
}

std::string monoStringToStdString(monoString* mStr) {
    return mStr ? std::string(mStr->toCString()) : "";
}

std::string getPlayerNickname(void* player) {
    return player ? monoStringToStdString(get_Nickname(player)) : "";
}

bool get_IsDieing(void* player) {
    bool (*Dieing)(void*) = (bool (*)(void*))getRealOffset(ENCRYPTOFFSET("0x1052524C4")); 
    return Dieing(player);
}

bool get_IsVisible(void* player) {
    bool (*IsVisible)(void*) = (bool (*)(void*))getRealOffset(ENCRYPTOFFSET("0x1052602E0"));  
    return IsVisible(player);
}

static void* GetLocalPlayer(void* Game) {
    void* (*_GetLocalPlayer)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x102B19008")); 
    return _GetLocalPlayer(Game);
}

static void* Curent_Match() {
    void* (*_Curent_Match)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x102426010"));  
    return _Curent_Match(NULL);
}

static Quaternion GetRotation(void* player) {
    Quaternion (*_GetRotation)(void*) = (Quaternion(*)(void*))getRealOffset(ENCRYPTOFFSET("0x105F3D744"));  
    return _GetRotation(player);
}

static bool get_isLocalTeam(void* player) {
    bool (*_get_isLocalTeam)(void*) = (bool (*)(void*))getRealOffset(ENCRYPTOFFSET("0x10526D118"));
    return _get_isLocalTeam(player);
}

static bool get_IsSighting(void* player) {
    bool (*_get_IsSighting)(void*) = (bool (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105252B44"));  
    return _get_IsSighting(player);
}

static bool get_IsFiring(void* player) {
    bool (*_get_IsFiring)(void*) = (bool (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105252A90"));  
    return _get_IsFiring(player);
}

static Vector3 WorldToScreenPoint(void* WorldCam, Vector3 WorldPos) {
    Vector3 (*_WorldToScreenScene)(void*, Vector3) = (Vector3 (*)(void*, Vector3))getRealOffset(ENCRYPTOFFSET("0x105EF6610"));  
    return _WorldToScreenScene(WorldCam, WorldPos);
}
/*
static void* GetHeadPositions(void* player) {
    void* (*_GetHeadPositions)(void*) = (void*(*)(void*))getRealOffset(ENCRYPTOFFSET("0x1052BECB8"));  
    return _GetHeadPositions(player);
}

static Vector3 GetHeadPosition(void* player) {
    return get_position(GetHeadPositions(player));
}
*/
static Vector3 CameraMain(void* player){
    return get_position(*(void**) ((uint64_t) player + 0x200)); 
}

static void* Component_GetTransform(void* player) {
    void* (*_Component_GetTransform)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105EF8D78"));  
    return _Component_GetTransform(player);
}

Vector3 getPosition(void* transform) {
    return get_position(Component_GetTransform(transform));
}   

static Vector3 GetForward(void* player) {
    Vector3 (*_GetForward)(void*) = (Vector3 (*)(void*))getRealOffset(ENCRYPTOFFSET("0x105F3DE1C"));  
    return _GetForward(player);
}

static Vector3 Transform_INTERNAL_GetPosition(void* player) {
    Vector3 out = Vector3::Zero();
    void (*_Transform_INTERNAL_GetPosition)(void*, Vector3*) = (void (*)(void*, Vector3*))getRealOffset(ENCRYPTOFFSET("0x105F3D49C"));
    _Transform_INTERNAL_GetPosition(player, &out);
    return out;
}

bool isFov(Vector3 vec1, Vector3 vec2, float diameter) {
    float radius = diameter * 0.5f; 
    return (pow(vec1.x - vec2.x, 2) + pow(vec1.y - vec2.y, 2)) <= pow(radius, 2);
}

std::vector<void*> players;
void clearPlayers() {
    if (!players.empty()) {
        players.erase(std::remove_if(players.begin(), players.end(), [](void* player) {
            return player == nullptr ||  !get_isLiving(player);
        }), players.end());
    }
}

bool playerFind(void *pl) {
    return std::find(players.begin(), players.end(), pl) != players.end();
}

Vector3 GetPlayerLocation(void* player) {
    return get_position(get_transform(player));
}

bool IsClientBot(void* _this) { return *(bool*)((uint64_t)_this + 0x2B0); }

void (*old_Update)(void*);
void Update(void* player) {
    if (player && (ESPEnable)) {
        if (!playerFind(player) && get_isLiving(player) && !Team(player)) {
            players.push_back(player);
        }
        clearPlayers();
                void* localplayers = Current_Local_Player();
                if (localplayers != NULL) {
                spofNick(localplayers);
                }
}
}

void OnDestroy(void* player) {
    if (player) {
        players.erase(std::remove(players.begin(), players.end(), player), players.end());
    }
}

namespace Save{
	void* DamageInfo;
	clock_t AimDelay;
	int AimFPS = (1000000 / 12);
}

void (*DamageInfo)(void*);
void DamageInfoHook(void* Player){
	Save::DamageInfo=Player;
}

void PlayerTakeDamage(void* ClosestEnemy){
    void* CurrentMatch = Curent_Match();
    void* LocalPlayer = GameFacadeCurrentLocalPlayer();
    if (!Camera_main() || !CurrentMatch || CurrentMatch == nullptr || LocalPlayer == nullptr || get_IsDieing(LocalPlayer) || !get_isLiving(LocalPlayer)) return;
	if (Save::DamageInfo != NULL && clock() > Save::AimDelay){
		Save::AimDelay = clock() + Save::AimFPS;
		
		void* WeaponOnHand = PlayerWeaponOnHand(LocalPlayer);
		*(void**)((uintptr_t) Save::DamageInfo + 0x28) = *(void**)((uintptr_t) LocalPlayer + 0x1E8);
		*(void**)((uintptr_t) Save::DamageInfo + 0x40) = WeaponOnHand;
		*(Vector3*)((uintptr_t) Save::DamageInfo + 0x4C) = CameraPosition(LocalPlayer);
		*(Vector3*)((uintptr_t) Save::DamageInfo + 0x58) = PlayerHeadPosition(ClosestEnemy);
		PlayerNetworkStartWholeBodyFiring(LocalPlayer,WeaponOnHand);
		PlayerTakeDamage(ClosestEnemy,Save::DamageInfo,NULL,*(void**)((uintptr_t) ClosestEnemy + 0xCD0),0);
		PlayerNetworkStopFire(LocalPlayer,WeaponOnHand);
	}
}

static void* Player_GetHeadCollider(void* player) {
    void* (*_Player_GetHeadCollider)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x10525B768"));
    return _Player_GetHeadCollider(player);
}

static void* get_WeaponData(void* player) {
    void* (*_get_WeaponData)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x1040D17B0"));
    return _get_WeaponData(player);
}

static Vector3 Transform_GetPosition(void* player) {
    Vector3 out = Vector3::Zero();
    void (*_Transform_GetPosition)(void*, Vector3*) = (void (*)(void*, Vector3*))getRealOffset(ENCRYPTOFFSET("0x105F3D49C"));
    _Transform_GetPosition(player, &out);
    return out;
}

static void Transform_INTERNAL_SetPosition(void* player, Vector3 inn) {
    void (*_Transform_INTERNAL_SetPosition)(void*, Vector3) = (void (*)(void*, Vector3))getRealOffset(ENCRYPTOFFSET("0x105F3D540"));
    _Transform_INTERNAL_SetPosition(player, inn);
}

static bool Physics_Raycast(Vector3 camLocation, Vector3 headLocation, unsigned int LayerID, void* collider) {
    bool (*_Physics_Raycast)(Vector3, Vector3, unsigned int, void*) = (bool(*)(Vector3, Vector3, unsigned int, void*))getRealOffset(ENCRYPTOFFSET("0x104BBB258"));  
    return _Physics_Raycast(camLocation, headLocation, LayerID, collider);
}

bool IsVisible(void* player){
    if(player) {
        Vector3 cameraLocation = Transform_GetPosition(Component_GetTransform(Camera_main()));
        Vector3 headLocation = Transform_GetPosition(Component_GetTransform(Player_GetHeadCollider(player)));
        void* hitObj = nullptr;
        return !Physics_Raycast(cameraLocation, headLocation, 12, &hitObj);
    }
    return false;
}

Quaternion GetRotationToLocation(Vector3 targetLocation, float y_bias, Vector3 myLoc) {
    return Quaternion::LookRotation((targetLocation + Vector3(0, y_bias, 0)) - myLoc, Vector3::Up());
}

static void set_aim(void* player, Quaternion look) {
    void (*_set_aim)(void*, Quaternion) = (void (*)(void*, Quaternion))getRealOffset(ENCRYPTOFFSET("0x10525CD8C")); 
    _set_aim(player, look);
}

static void* get_CurrentLocalPlayer() {
    void* (*_get_CurrentLocalPlayer)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x1024264E0"));
    return _get_CurrentLocalPlayer(nullptr);
}

static void* get_LocalPlayerOrObServer() {
    void* (*_get_LocalPlayerOrObServer)(void*) = (void* (*)(void*))getRealOffset(ENCRYPTOFFSET("0x102426BDC"));
    return _get_LocalPlayerOrObServer(nullptr);
}


void* targetEnemy = nullptr; 
static float lastTargetChangeTime = 0.0f;

bool IsTargetInPlayerView(void* player, void* target) {
    Vector3 playerForward = GetForward(Component_GetTransform(Camera_main())); 
    Vector3 playerToTarget = Vector3::Normalized(GetHeadPosition(target) - CameraMain(player)); 
    return RAD2DEG(acos(Vector3::Dot(playerForward, playerToTarget))) <= AimbotFOV / 6.0f; 
}


void DrawBox(float X, float Y, float W, float H, ImColor Color, float curve, float thickness)
{
	ImDrawList* draw_list = ImGui::GetForegroundDrawList();
    // Vẽ box trong suốt
	draw_list->AddRect(ImVec2(X + 1, Y + 1), ImVec2(X + W - 1, Y + H - 1), Color);
	// Vẽ viền box
	draw_list->AddRect(ImVec2(X, Y), ImVec2(X + W, Y + H), Color, curve, thickness);
}
void DrawEsp() {
    ImDrawList* drawList = ImGui::GetBackgroundDrawList(); // Lấy đối tượng để vẽ trên màn hình
    int numberOfPlayersAround = 0;
    bool hasPlayers = !players.empty(); // Kiểm tra xem có player nào trong danh sách players không
    bool anyPlayerInFOV = false; // Biến kiểm tra xem có player nào trong tầm nhìn không
    ImVec2 screenCenter(ImGui::GetIO().DisplaySize.x / 2, ImGui::GetIO().DisplaySize.y / 2); // Tính tọa độ trung tâm màn hình
    if (ESPEnable && hasPlayers) { // Nếu ESP được bật và có players
        for (int i = 0; i < players.size(); i++) { // Duyệt qua danh sách players
            auto* player = players[i]; // Lấy player hiện tại
            if (!player || !get_main() || IsTeammate(player)) { // Nếu player không hợp lệ, không có camera chính hoặc là đồng đội thì bỏ qua
                continue;
            }
numberOfPlayersAround++;
            auto pos = get_position(get_transform(player)); // Lấy vị trí của player
            auto viewpos = get_position(get_transform(get_main())); // Lấy vị trí của camera chính
            bool w2sCheck = false; // Biến kiểm tra xem player có nằm trong tầm nhìn không

            world2screen_c(pos + Vector3(0, 0.75f, 0), w2sCheck); // Chuyển đổi vị trí của player từ tọa độ thế giới sang tọa độ màn hình
            Vector3 headPos = GetPlayerLocation(player) + Vector3(0, 1.6f, 0); // Lấy vị trí đầu của player
            Vector3 footPos = GetPlayerLocation(player) + Vector3(0, 0.0f, 0); // Lấy vị trí chân của player

            ImVec2 top_pos = world2screen_i(headPos); // Chuyển đổi vị trí đầu sang tọa độ màn hình
            ImVec2 bot_pos = world2screen_i(footPos); // Chuyển đổi vị trí chân sang tọa độ màn hình
            float boxHeight = fabs(top_pos.y - bot_pos.y); // Tính chiều cao của box ESP
            float boxWidth = boxHeight * 0.65f; // Tính chiều rộng của box ESP

            float segmentWidth = boxWidth / 4.0f; // Tính chiều rộng của mỗi đoạn trong box ESP
            float segmentHeight = boxHeight / 4.0f; // Tính chiều cao của mỗi đoạn trong box ESP

            ImVec2 top_left(top_pos.x - boxWidth / 2.0f, top_pos.y); // Tính tọa độ góc trên bên trái của box ESP
            ImVec2 top_right(top_pos.x + boxWidth / 2.0f, top_pos.y); // Tính tọa độ góc trên bên phải của box ESP
            ImVec2 bottom_left(bot_pos.x - boxWidth / 2.0f, bot_pos.y); // Tính tọa độ góc dưới bên trái của box ESP
            ImVec2 bottom_right(bot_pos.x + boxWidth / 2.0f, bot_pos.y); // Tính tọa độ góc dưới bên phải của box ESP

            
            float circleRadius = 90.0f; // Bán kính của vòng tròn FOV
            ImVec2 enemyPos = world2screen_i(GetPlayerLocation(player)); // Chuyển đổi vị trí của player sang tọa độ màn hình
            float angle = atan2f(enemyPos.y - screenCenter.y, enemyPos.x - screenCenter.x); // Tính góc giữa player và tâm màn hình

            float arrowTipX = screenCenter.x + circleRadius * cos(angle); // Tính tọa độ mũi tên ESP
            float arrowTipY = screenCenter.y + circleRadius * sin(angle); // Tính tọa độ mũi tên ESP

            ImVec2 botPos = world2screen_i(pos + Vector3(0, -0.15f, 0)); // Tính tọa độ chân của player
            ImVec2 topPos = world2screen_i(pos + Vector3(0, 1.9f, 0)); // Tính tọa độ đầu của player

            ImVec2 playerMidPos = ImVec2(
                (topPos.x + botPos.x) / 2, // Tính tọa độ trung bình theo chiều ngang
                (topPos.y + botPos.y) / 2 // Tính tọa độ trung bình theo chiều dọc
            );
            float deltaX = playerMidPos.x - screenCenter.x; // Tính khoảng cách theo chiều ngang giữa player và tâm màn hình
            float deltaY = playerMidPos.y - screenCenter.y; // Tính khoảng cách theo chiều dọc giữa player và tâm màn hình
            float distanceFromCenter = sqrt(deltaX * deltaX + deltaY * deltaY); // Tính khoảng cách giữa player và tâm màn hình
            


            float baseAngle1 = angle + (5.0f * M_PI / 6.0f); // Tính góc cơ sở 1 cho mũi tên ESP
            float baseAngle2 = angle - (5.0f * M_PI / 6.0f); // Tính góc cơ sở 2 cho mũi tên ESP

            float arrowBaseX1 = arrowTipX + 10.0f * cos(baseAngle1); // Tính tọa độ đáy mũi tên ESP 1
            float arrowBaseY1 = arrowTipY + 10.0f * sin(baseAngle1); // Tính tọa độ đáy mũi tên ESP 1
            float arrowBaseX2 = arrowTipX + 10.0f * cos(baseAngle2); // Tính tọa độ đáy mũi tên ESP 2
            float arrowBaseY2 = arrowTipY + 10.0f * sin(baseAngle2); // Tính tọa độ đáy mũi tên ESP 2

            int health = get_CurHP(player); // Lấy máu hiện tại của player
            int maxhp = get_MaxHP(player); // Lấy máu tối đa của player
            float HPBarWidth = 70.0f; // Chiều rộng của thanh máu
            float HPBarHeight = 4.5f; // Chiều cao của thanh máu
            ImColor healthColor; // Màu của thanh máu
            ImVec2 HPBarCenter(top_pos.x, top_pos.y - 25); // Tọa độ trung tâm của thanh máu
            ImVec2 HPBarTopLeft(HPBarCenter.x - HPBarWidth / 2, HPBarCenter.y - HPBarHeight / 2); // Tọa độ góc trên bên trái của thanh máu
            ImVec2 HPBarBottomRight(HPBarTopLeft.x + (HPBarWidth * health / maxhp), HPBarTopLeft.y + HPBarHeight); // Tọa độ góc dưới bên phải của thanh máu
            float rounding = HPBarHeight / 2.0f; // Độ bo tròn của thanh máu
            float lineBox = 0.9f; // Độ dày của đường viền box ESP
            ImVec4 boxColor, lineColor; // Màu của box ESP và đường viền

            if (get_IsDieing(player)) { // Nếu player đang chết
                boxColor = ImColor(255, 0, 0); // Màu đỏ
                lineColor = ImColor(255, 0, 0); // Màu đỏ
            }
            else { // Nếu player không chết
              lineColor = ImVec4(0.0f, 0.8f, 1.0f, 1.0f); // Màu xanh dương neon phát sáng
              boxColor = ImVec4(0.0f, 0.8f, 1.0f, 1.0f); // Màu xanh dương neon phát sáng

            }

            Vector3 playerLocation = GetPlayerLocation(player); // Lấy vị trí của player
            Vector3 cameraLocation = GetPlayerLocation(get_main()); // Lấy vị trí của camera chính

            // Tính khoảng cách giữa player và camera chính
            float distance = Vector3::Distance(playerLocation, cameraLocation);

            if (distance > 800) { // Nếu khoảng cách lớn hơn 400 thì bỏ qua
                continue;
            }
            
            if (ESPArrow) { // Nếu mũi tên ESP được bật

                float distanceToEnemy = sqrtf(powf(enemyPos.x - screenCenter.x, 2) + powf(enemyPos.y - screenCenter.y, 2)); // Tính khoảng cách giữa player và tâm màn hình
                ImColor dotColor = IsClientBot(player) ? ImColor(0, 255, 0) : (getPlayerNickname(player) != "" ? ImColor(255, 0, 0) : ImColor(255, 255, 255)); // Xác định màu của chấm ESP
                drawList->AddTriangleFilled(ImVec2(arrowTipX, arrowTipY), ImVec2(arrowBaseX1, arrowBaseY1), ImVec2(arrowBaseX2, arrowBaseY2), ImColor(0, 255, 0)); // Vẽ chấm ESP
            }

            if (distance > sliderDistanceValue) { // Nếu khoảng cách lớn hơn sliderDistanceValue thì bỏ qua
                continue;
            }
            auto pmtXtop = top_pos.x; // Tọa độ x của đỉnh box ESP
            auto pmtXbottom = bot_pos.x; // Tọa độ x của đáy box ESP
            if (top_pos.x > bot_pos.x) { // Nếu tọa độ x của đỉnh lớn hơn tọa độ x của đáy
                pmtXtop = bot_pos.x; // Hoán đổi tọa độ
                pmtXbottom = top_pos.x; // Hoán đổi tọa độ
            }

            float positionCalc = fabs((top_pos.y - bot_pos.y) * (0.0092f / 0.019f) / 2); // Tính toán vị trí của box ESP
            ImRect rect(ImVec2(pmtXtop - positionCalc, top_pos.y), ImVec2(pmtXbottom + positionCalc, bot_pos.y)); 
            if (w2sCheck) { 

if (ESPLine) {
                   ImColor lineColor = (targetEnemy != nullptr && targetEnemy == player && IsVisible(targetEnemy)) 
                                        ? ImColor(0, 255, 0) 
                                        : ImColor(255, 255, 255); 
    float offset = 55.0f;
    ImGui::GetBackgroundDrawList()->AddLine(
        {ImGui::GetIO().DisplaySize.x / 2, offset},               // Thay đổi y của điểm đầu
        {rect.GetCenter().x, rect.Min.y}, ImColor(0, 255, 0), 0.9
    );
}

if (ESPName) {
    auto playerName = getPlayerNickname(player);
    // Dời vị trí y xuống thêm 2 pixel
    ImVec2 namePosition((rect.Min.x + rect.Max.x) * 0.5f - 30, rect.Min.y - 7);

    ImVec2 textSize = ImGui::CalcTextSize(playerName.c_str());
ImVec2 backgroundMin(namePosition.x - 0, namePosition.y - 12); // Giảm giá trị -17 thành -12
ImVec2 backgroundMax(backgroundMin.x + textSize.x + 17, backgroundMin.y + textSize.y + 2); // Giảm chiều cao từ +5 xuống +2


    std::string playerNumber = std::to_string(numberOfPlayersAround) + "   ";
    std::string playerNameWithNumber = playerNumber + playerName;

    //float squareSize = textSize.y + 4;
    //ImVec2 squareMin(backgroundMin.x, backgroundMin.y);
    //ImVec2 squareMax(squareMin.x + squareSize, squareMin.y + squareSize);

    float squareSize = textSize.y - 2; // Giảm chiều cao hình vuông
ImVec2 squareMin(backgroundMin.x, backgroundMin.y + 1); // Dời khung lên trên một chút
ImVec2 squareMax(squareMin.x + squareSize, squareMin.y + squareSize);

ImGui::GetBackgroundDrawList()->AddRectFilled(squareMin, squareMax, ImColor(0, 255, 0, 200), 0.0f);
    ImGui::GetBackgroundDrawList()->AddRectFilled(backgroundMin, backgroundMax, ImColor(0, 0, 0, 100), 5.0f);
    ImGui::GetBackgroundDrawList()->AddText(ImGui::GetFont(), 12.0f, ImVec2(backgroundMin.x + 7, backgroundMin.y + 2), ImColor(255, 255, 0, 225), playerNameWithNumber.c_str());

}


                if (get_isLiving(player)) { // Nếu player còn sống
                    if (get_IsDieing(player)) { // Nếu player đang chết
                        healthColor = ImColor(255, 0, 0); // Màu đỏ
                    }
                    else if (health >= 140) { // Nếu máu lớn hơn hoặc bằng 140
                        healthColor = ImColor(0, 255, 0); // Màu xanh lá
                    }
                    else if (health >= 80 && health < 140) { // Nếu máu từ 80 đến 139
                        healthColor = ImColor(255, 255, 0); // Màu vàng
                    }
                    else { // Nếu máu nhỏ hơn 80
                        healthColor = ImColor(255, 0, 0); // Màu đỏ
                    }
                    if (ESPBox) { // Nếu ESP Box được bật
                    ImColor boxColor = ImColor(0, 255, 0);
                    

                    float height =  abs(enemyPos.y - top_pos.y);
                    float width = height * 0.55f;
                    DrawBox(top_pos.x - (width * 0.4),  top_pos.y, width, height, ImColor(255, 255, 255), 0.9, 0.9);
}

                    if (ESPHealth)
                            {
                                float playerHealth = static_cast<float>(get_CurHP(player));
                                float healthPercentage = playerHealth / 200.0f;
                                float healthBarHeight = rect.Max.y - rect.Min.y;
                                ImVec2 healthBarPos(rect.Min.x - 10, rect.Min.y);
                                float healthFilledHeight = healthBarHeight * healthPercentage;

                                 ImU32 healthColor = ImColor(0, 255, 0);
                        if (healthPercentage <= 0.7f) {
                            healthColor = ImColor(255, 0, 0);
                        } else if (healthPercentage <= 1.5f) {
                            healthColor = ImColor(255, 255, 0);
                        }
                                drawList->AddRectFilled(healthBarPos, ImVec2(healthBarPos.x + 5, healthBarPos.y + healthFilledHeight), healthColor, 2.0f);
                                drawList->AddRect(healthBarPos, ImVec2(healthBarPos.x + 5, healthBarPos.y + healthBarHeight), ImColor(255, 255, 255), 2.0f, 0, 1.0f);   
                            }

if (bone) {
                            ImColor boneColor = ImColor(127,255,212); 

                            Vector3 headPos = GetHeadPosition(player);
                            Vector3 neckPos = GetNeckPosition(player);
                            Vector3 hipPos = GetHipPosition(player);
                            Vector3 leftAnklePos = GetLeftAnkleTFs(player);
                            Vector3 rightAnklePos = GetRightAnkleTFs(player);
                            Vector3 leftToePos = GetLeftToeTFs(player);
                            Vector3 rightToePos = GetRightToeTFs(player);
                            Vector3 leftHandPos = getLeftHandTFs(player); 
                            Vector3 rightHandPos = getRightHandTFs(player);  
                            Vector3 leftForeArmPos = getLeftForeArmTFs(player);  
                            Vector3 rightForeArmPos = getRightForeArmTFs(player);  

                            Vector3 cameraPos = get_position(get_transform(get_main()));
                            //float distance = DistanceBetween(cameraPos, headPos);


                            float baseRadius = 5.0f;  
                            float adjustedRadius = baseRadius / (distance / 10.0f); 

                            float minRadius = 1.0f;  
                            float maxRadius = 10.0f;  
                            float finalRadius = clamp(adjustedRadius, minRadius, maxRadius);

                            headPos.y += 0.1f;

                            ImVec2 headScreenPos = world2screen_i(headPos);
                            ImVec2 neckScreenPos = world2screen_i(neckPos);
                            ImVec2 hipScreenPos = world2screen_i(hipPos);
                            ImVec2 leftAnkleScreenPos = world2screen_i(leftAnklePos);
                            ImVec2 rightAnkleScreenPos = world2screen_i(rightAnklePos);
                            ImVec2 leftToeScreenPos = world2screen_i(leftToePos);
                            ImVec2 rightToeScreenPos = world2screen_i(rightToePos);
                            ImVec2 leftHandScreenPos = world2screen_i(leftHandPos);  
                            ImVec2 rightHandScreenPos = world2screen_i(rightHandPos);  
                            ImVec2 leftForeArmScreenPos = world2screen_i(leftForeArmPos);  
                            ImVec2 rightForeArmScreenPos = world2screen_i(rightForeArmPos);  

                            drawList->AddCircle(headScreenPos, finalRadius, boneColor, 0, 1.0f);

                            drawList->AddLine(headScreenPos, neckScreenPos, boneColor, 1.0f); 
                            drawList->AddLine(neckScreenPos, hipScreenPos, boneColor, 1.0f);   
                            drawList->AddLine(hipScreenPos, leftAnkleScreenPos, boneColor, 1.0f); 
                            drawList->AddLine(hipScreenPos, rightAnkleScreenPos, boneColor, 1.0f); 
                            drawList->AddLine(leftAnkleScreenPos, leftToeScreenPos, boneColor, 1.0f);
drawList->AddLine(rightAnkleScreenPos, rightToeScreenPos, boneColor, 1.0f); 

                            drawList->AddLine(neckScreenPos, leftForeArmScreenPos, boneColor, 1.0f);  
                            drawList->AddLine(neckScreenPos, rightForeArmScreenPos, boneColor, 1.0f); 
                            drawList->AddLine(leftForeArmScreenPos, leftHandScreenPos, boneColor, 1.0f);  
                            drawList->AddLine(rightForeArmScreenPos, rightHandScreenPos, boneColor, 1.0f); 
                        }



                if (ESPDistance) { // Nếu ESP Distance được bật
                        char distanceText[32];
                        sprintf(distanceText, "[%.0f M]", distance);
                        ImVec2 textSize = ImGui::GetFont()->CalcTextSizeA(ImGui::GetFontSize() * 0.50f, FLT_MAX, 0.0f, distanceText);
                        ImVec2 textPosition = ImVec2(HPBarTopLeft.x + 1, HPBarTopLeft.y - textSize.y / 1); // Vị trí khoảng cách (bên cạnh máu)
                        drawList->AddText(ImGui::GetFont(), ImGui::GetFontSize() * 0.55f, textPosition, ImColor(255, 255, 255), distanceText);
                    }

                }
            }    
        }

        

        
        if (ESPCount) { 
        char playerCountText[32]; 

    // Set the desired font size
        float fontSize = 48.0f;

    // Use default font
        ImGuiIO& io = ImGui::GetIO();
        ImFont* font = io.Fonts->Fonts[0]; // Use default font

    // Push the new font size
        ImGui::PushFont(font);

    // Format the player count text
        sprintf(playerCountText, "%zu", players.size());

    // Calculate the text width and height
        ImVec2 textSize = ImGui::CalcTextSize(playerCountText);

    // Position the text slightly above and a bit to the left of the center
        ImVec2 textPosition(
        (ImGui::GetIO().DisplaySize.x - textSize.x) / 2 - 10,  // Slightly left of the center
        20.0f // Place the text near the top of the screen (you can adjust this value as needed)
        );

        ImU32 color = ImColor(255, 0, 0);  // Red color for the text

    // Render the text at the screen position
        ImGui::GetBackgroundDrawList()->AddText(font, fontSize, textPosition, color, playerCountText);

    // Pop the font to revert to the original font
        ImGui::PopFont();
    }    
}  


        if (Aimkill) {
            for (int i = 0; i < players.size(); i++) {
                auto* player = players[i];
                if (!player || !Camera_main() || !get_isLiving(player) || IsTeammate(player)) continue;

                void* CurrentMatch = Curent_Match();
                void* LocalPlayer = GetLocalPlayer(CurrentMatch);
                if (LocalPlayer == nullptr || CurrentMatch == nullptr) continue;

                float closestDistance = FLT_MAX;
                void* closestEnemy = nullptr;

                if (LocalPlayer && CurrentMatch) {
                    float currentTime = ImGui::GetTime();
                    if (currentTime - lastTargetChangeTime >= 4.0f) {
                        targetEnemy = nullptr;
                        lastTargetChangeTime = currentTime;
                    }

                    if (targetEnemy && get_isLiving(targetEnemy) && !IsTeammate(targetEnemy) && !get_IsDieing(targetEnemy)) {
                        if (IsVisible(targetEnemy)) {
                            if (Vector3::Distance(GetHeadPosition(targetEnemy), CameraMain(LocalPlayer)) <= AimDis) {
                                closestEnemy = targetEnemy;
                            } else {
                                targetEnemy = nullptr;
                                lastTargetChangeTime = 0.0f;
                            }
                        } else {
                            targetEnemy = nullptr;
                            lastTargetChangeTime = 0.0f;
                        }
                    }

                    if (closestEnemy == nullptr) {
                        for (auto& enemy : players) {
                            if (enemy && !IsTeammate(enemy) && !get_IsDieing(enemy)) {
                                if (IsVisible(enemy)) {
                                    float distance = Vector3::Distance(GetHeadPosition(enemy), CameraMain(LocalPlayer));
                                    if (distance <= AimDis && distance < closestDistance) {
                                        closestDistance = distance;
                                        closestEnemy = enemy;
                                    }
                                }
                            }
                        }
                    }

                    if (closestEnemy) {
                        targetEnemy = closestEnemy;
                        PlayerTakeDamage(closestEnemy);
                    } else {
                        targetEnemy = nullptr;
                    }
                }
            }
        }
        if (Telekill) {
            for (int i = 0; i < players.size(); i++) {
                auto* player = players[i];
                if (!player || !Camera_main() || !get_isLiving(player) || IsTeammate(player)) continue;

                void* CurrentMatch = Curent_Match();
                void* LocalPlayer = GetLocalPlayer(CurrentMatch);
                if (LocalPlayer == nullptr || CurrentMatch == nullptr) continue;

                float closestDistance = FLT_MAX;
                void* closestEnemy = nullptr;

                if (LocalPlayer && CurrentMatch) {
                    float currentTime = ImGui::GetTime();
                    if (currentTime - lastTargetChangeTime >= 4.0f) {
                        targetEnemy = nullptr;
                        lastTargetChangeTime = currentTime;
                    }

                    if (targetEnemy && get_isLiving(targetEnemy) && !IsTeammate(targetEnemy) && !get_IsDieing(targetEnemy)) {
                        if (Vector3::Distance(GetHeadPosition(targetEnemy), CameraMain(LocalPlayer)) <= AimDis) {
                            
                                closestEnemy = targetEnemy;
                            
                        } else {
                            targetEnemy = nullptr;
                            lastTargetChangeTime = 0.0f;
                        }
                    }

                    if (closestEnemy == nullptr) {
                        for (auto& enemy : players) {
                            if (enemy && !IsTeammate(enemy) && !get_IsDieing(enemy)) {
                                
                                    float distance = Vector3::Distance(GetHeadPosition(enemy), CameraMain(LocalPlayer));
                                    if (distance <= AimDis && distance < closestDistance) {
                                        closestDistance = distance;
                                        closestEnemy = enemy;
                                    }
                                
                            }
                        }
                    }

                    if (closestEnemy) {
                        targetEnemy = closestEnemy;
                        
                        void *_MountTF = get_transform(closestEnemy);
                        if (_MountTF != NULL) {
                            Vector3 MountTF =Transform_INTERNAL_GetPosition(_MountTF) -(GetForward(_MountTF) * 0.0f);
                                Transform_INTERNAL_SetPosition(get_transform(LocalPlayer),Vvector3(MountTF.x, MountTF.y, MountTF.z));
                            }
                        
                    } else {
                        targetEnemy = nullptr;
                    }
                }
            }
        }

            ImDrawList* draw_list = ImGui::GetBackgroundDrawList();

        if (Aimbot) {

            if (Fov) draw_list->AddCircle(ImVec2(kWidth/2, kHeight/2), circle_size, ImColor(0, 255, 0));

            for (int i = 0; i < players.size(); i++) {
                auto* player = players[i]; 
                if (!player || !Camera_main() || !get_isLiving(player) || IsTeammate(player)) continue;

                void* CurrentMatch = Curent_Match();
                void* LocalPlayer = GetLocalPlayer(CurrentMatch);
                if (LocalPlayer == nullptr || CurrentMatch == nullptr) continue;

                float closestDistance = FLT_MAX;
                void* closestEnemy = nullptr;

                if (LocalPlayer && CurrentMatch) {
                    float currentTime = ImGui::GetTime();
                    if (currentTime - lastTargetChangeTime >= 4.0f) {
                        targetEnemy = nullptr;
                        lastTargetChangeTime = currentTime;
                    }

                    if (targetEnemy && get_isLiving(targetEnemy) && !IsTeammate(targetEnemy) && !get_IsDieing(targetEnemy)) {
                        if (IsTargetInPlayerView(LocalPlayer, targetEnemy)) {
                            if (IsVisible(targetEnemy) && Vector3::Distance(GetHeadPosition(targetEnemy), CameraMain(LocalPlayer)) <= AimDis) {
                                closestEnemy = targetEnemy;
                            } else {
                                targetEnemy = nullptr;
                                lastTargetChangeTime = 0.0f;
                            }
                        } else {
                            targetEnemy = nullptr;
                            lastTargetChangeTime = 0.0f;
                        }
                    }

                    if (closestEnemy == nullptr) {
                        for (auto& enemy : players) {
                            if (enemy && !IsTeammate(enemy) && !get_IsDieing(enemy) && IsTargetInPlayerView(LocalPlayer, enemy)) {
                                if (IsVisible(enemy)) {
                                    float distance = Vector3::Distance(GetHeadPosition(enemy), CameraMain(LocalPlayer));
                                    if (distance <= AimDis && distance < closestDistance) {
                                        closestDistance = distance;
                                        closestEnemy = enemy;
                                    }
                                }
                            }
                        }
                    }

                    if (closestEnemy) {
                        targetEnemy = closestEnemy;
                        Vector3 EnemyLocation = GetHeadPosition(closestEnemy);
                        Vector3 PlayerLocation = CameraMain(LocalPlayer);
                        Quaternion PlayerLook = GetRotationToLocation(EnemyLocation, 0.1f, PlayerLocation);
                        bool IsScopeOn = get_IsSighting(LocalPlayer);
                        bool IsFiring = get_IsFiring(LocalPlayer);
                        

                        if (AimWhen == 0) {
                            set_aim(LocalPlayer, PlayerLook);
                        } else if (AimWhen == 1 && IsFiring) {
                            set_aim(LocalPlayer, PlayerLook);
                        } else if (AimWhen == 2 && IsScopeOn) {
                            set_aim(LocalPlayer, PlayerLook);
                        }
                    } else {
                        targetEnemy = nullptr;
                    }
                }
            }
        } else {
            players.clear();
            targetEnemy = nullptr;
        }
    }
//}

#endif  // ESP_H