#ifndef VISUALS_CPP
#define VISUALS_CPP
#include <core/inc.hpp>

auto cheat_interface::c_visual::render() -> void
{
	try {

		if ( !g_ctx ) return;

		if ( !g_ctx->view_state ) return;

		g_ctx->view_state->viewmatrix();

		if ( g_ctx->size() < 1 ) return;

		auto closest_player = object::c_closest();
		auto crosshair_space = FLT_MAX;

		g_aimbot->closest_actor = closest_player;

		for ( auto& player : g_ctx->m_players )
		{
			if ( !player.m_mesh ) continue;

			auto transform = player.m_mesh->bone_array().get_itter();
			if ( !transform.data() ) continue;

			auto head_bone = player.m_mesh->get_bone_location( game::gve<engine::transform>( transform, 110 ) );
			if ( !head_bone.is_valid() ) continue;

			head_bone.z += 20.f;

			auto root_bone = player.m_mesh->get_bone_location( game::gve<engine::transform>( transform, 0 ) );
			if ( !root_bone.is_valid() ) continue;

			int distance = g_ctx->in_lobby ? 10.0f : g_engine->location.distance_to( root_bone );
			if ( distance > g_vars->visuals.render_distance ) continue;

			auto head_screen = g_engine->world_to_screen( head_bone );
			auto root_screen = g_engine->world_to_screen( root_bone );

			player.m_is_on_screen = g_engine->in_screen( head_screen ) && g_engine->in_screen( root_screen );

			auto get_actor_bound_fn = player.m_mesh->get_player_dimensions( &player.o );
			if ( !get_actor_bound_fn ) player.m_is_on_screen = false;

			auto actor_height = player.o.bottom - player.o.top;
			auto actor_width = player.o.right - player.o.left;

			auto corner_width = actor_width / 4;
			auto corner_height = actor_height / 3;

			auto distance_difference = 225.0 - distance;
			auto distance_offset = distance_difference * 0.03;
			auto bottom_middle_offset = math::vector2(
				player.o.left + ( actor_width / 2.0 ),
				player.o.bottom
			);

			auto dist = g_engine->get_cross_distance( head_screen.x, head_screen.y, g_engine->width_center, g_engine->height_center );
			const auto is_bot = !g_ctx->in_lobby && player.is_bot;

			if ( dist < crosshair_space && !g_ctx->in_lobby )
			{
				closest_player.m_actor = player.m_actor;
				closest_player.m_mesh = player.m_mesh;
				closest_player.m_state = player.m_state;
				closest_player.m_root_component = player.m_root_component;

				closest_player.m_username = player.m_username;
				closest_player.distance = distance;
				closest_player.is_visible = player.is_visible;
				closest_player.is_dbno = player.is_dbno;
				closest_player.is_teammate = player.m_is_teammate;
				closest_player.m_head_screen = head_screen;
				closest_player.m_root_screen = root_screen;
				closest_player.crosshair_space = dist;

				crosshair_space = dist;
			}

			if ( friendly_map.count( player.m_actor ) ) {
				player.m_is_friendly = friendly_map[ player.m_actor ];
			}

			if ( enemy_map.count( player.m_actor ) ) {
				player.m_is_enemy = enemy_map[ player.m_actor ];
			}

			auto bottom_offset_bounding = 5.00f;
			auto top_offset_bounding = 20.00f;

			auto padding_text = 2.50f;

			ImColor set_box_color, set_dot_color, set_hat_color, set_arrow_color, set_skeleton_color, set_skeleton_joint_color, set_arrow_fill_color, set_fill_color, set_platform_color, set_rank_color, set_view_angle_color, set_killscore_color, set_teamid_color, set_username_color, set_distance_color;
			ImColor set_text_color = ImColor( g_vars->colors.text_color[ 0 ], g_vars->colors.text_color[ 1 ], g_vars->colors.text_color[ 2 ] );

			if ( g_vars->visuals.boxes ) {
				set_box_color = ImColor( g_vars->colors.box_color[ 0 ], g_vars->colors.box_color[ 1 ], g_vars->colors.box_color[ 2 ], g_vars->colors.box_color[ 3 ] );
			}

			if ( g_vars->visuals.corners ) {
				set_box_color = ImColor( g_vars->colors.corner_box_color[ 0 ], g_vars->colors.corner_box_color[ 1 ], g_vars->colors.corner_box_color[ 2 ], g_vars->colors.corner_box_color[ 3 ] );
			}

			if ( g_vars->visuals.rotating ) {
				set_box_color = ImColor( g_vars->colors.rotating_color[ 0 ], g_vars->colors.rotating_color[ 1 ], g_vars->colors.rotating_color[ 2 ], g_vars->colors.rotating_color[ 3 ] );
			}

			if ( g_vars->visuals.skeleton ) {
				set_skeleton_color = ImColor( g_vars->colors.skeleton_color[ 0 ], g_vars->colors.skeleton_color[ 1 ], g_vars->colors.skeleton_color[ 2 ], g_vars->colors.skeleton_color[ 3 ] );
			}

			if ( g_vars->visuals.skeleton_joints ) {
				set_skeleton_joint_color = ImColor( g_vars->colors.skeleton_joints_color[ 0 ], g_vars->colors.skeleton_joints_color[ 1 ], g_vars->colors.skeleton_joints_color[ 2 ], g_vars->colors.skeleton_joints_color[ 3 ] );
			}

			if ( g_vars->visuals.boxes_filled ) {
				set_fill_color = ImColor( g_vars->colors.fill_box_color[ 0 ], g_vars->colors.fill_box_color[ 1 ], g_vars->colors.fill_box_color[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
			}

			if ( g_vars->visuals.arrows ) {
				set_arrow_color = ImColor( g_vars->colors.arrows_color[ 0 ], g_vars->colors.arrows_color[ 1 ], g_vars->colors.arrows_color[ 2 ], g_vars->colors.arrows_color[ 3 ] );
			}

			if ( g_vars->visuals.filled_arrows ) {
				set_arrow_fill_color = ImColor( g_vars->colors.arrows_filled_color[ 0 ], g_vars->colors.arrows_filled_color[ 1 ], g_vars->colors.arrows_filled_color[ 2 ], g_vars->colors.arrows_filled_color[ 3 ] );
			}

			if ( g_vars->visuals.view_direction ) {
				set_view_angle_color = ImColor( g_vars->colors.view_angle_color[ 0 ], g_vars->colors.view_angle_color[ 1 ], g_vars->colors.view_angle_color[ 2 ] );
			}

			if ( g_vars->visuals.kill_count ) {
				set_killscore_color = ImColor( g_vars->colors.kill_color[ 0 ], g_vars->colors.kill_color[ 1 ], g_vars->colors.kill_color[ 2 ] );
			}

			if ( g_vars->visuals.team ) {
				set_teamid_color = ImColor( g_vars->colors.team_color[ 0 ], g_vars->colors.team_color[ 1 ], g_vars->colors.team_color[ 2 ] );
			}

			if ( g_vars->visuals.china_hat ) {
				set_hat_color = ImColor( g_vars->colors.hat_color[ 0 ], g_vars->colors.hat_color[ 1 ], g_vars->colors.hat_color[ 2 ], g_vars->colors.hat_color[ 3 ] );
			}

			if ( g_vars->visuals.username ) {
				set_username_color = ImColor( g_vars->colors.username_color[ 0 ], g_vars->colors.username_color[ 1 ], g_vars->colors.username_color[ 2 ] );;
			}

			if ( g_vars->visuals.distance ) {
				set_distance_color = ImColor( g_vars->colors.distance_color[ 0 ], g_vars->colors.distance_color[ 1 ], g_vars->colors.distance_color[ 2 ] );
			}

			if ( g_vars->visuals.rank ) {
				set_rank_color = ImColor( g_vars->colors.rank_color[ 0 ], g_vars->colors.rank_color[ 1 ], g_vars->colors.rank_color[ 2 ] );
			}

			if ( g_vars->visuals.radar ) {
				set_dot_color = ImColor( g_vars->radar.radar_dot_color[ 0 ], g_vars->radar.radar_dot_color[ 1 ], g_vars->radar.radar_dot_color[ 2 ] );
			}

			if ( g_vars->visuals.visibility_check )
			{
				if ( player.is_visible ) {

					ImColor visible_color = ImColor( g_vars->colors.player_visible[ 0 ], g_vars->colors.player_visible[ 1 ], g_vars->colors.player_visible[ 2 ] );
					ImColor text_color = ImColor( g_vars->colors.text_visible[ 0 ], g_vars->colors.text_visible[ 1 ], g_vars->colors.text_visible[ 2 ] );

					set_box_color = visible_color;
					set_text_color = text_color;
					set_arrow_color = visible_color;
					set_skeleton_color = visible_color;
					set_dot_color = visible_color;
					set_arrow_fill_color = visible_color;
					set_platform_color = visible_color;
					set_rank_color = visible_color;
					set_view_angle_color = visible_color;
					set_killscore_color = visible_color;
					set_teamid_color = visible_color;
					set_skeleton_joint_color = visible_color;
					set_distance_color = visible_color;
					set_username_color = visible_color;

					set_fill_color = ImColor( g_vars->colors.player_visible[ 0 ], g_vars->colors.player_visible[ 1 ], g_vars->colors.player_visible[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
				}

				if ( !player.is_visible ) {

					ImColor invisible_color = ImColor( g_vars->colors.player_invisible[ 0 ], g_vars->colors.player_invisible[ 1 ], g_vars->colors.player_invisible[ 2 ] );
					ImColor text_color = ImColor( g_vars->colors.text_invisible[ 0 ], g_vars->colors.text_invisible[ 1 ], g_vars->colors.text_invisible[ 2 ] );

					set_box_color = invisible_color;
					set_text_color = text_color;
					set_arrow_color = invisible_color;
					set_skeleton_color = invisible_color;
					set_dot_color = invisible_color;
					set_arrow_fill_color = invisible_color;
					set_platform_color = invisible_color;
					set_rank_color = invisible_color;
					set_view_angle_color = invisible_color;
					set_killscore_color = invisible_color;
					set_teamid_color = invisible_color;
					set_skeleton_joint_color = invisible_color;
					set_distance_color = invisible_color;
					set_username_color = invisible_color;

					set_fill_color = ImColor( g_vars->colors.player_invisible[ 0 ], g_vars->colors.player_invisible[ 1 ], g_vars->colors.player_invisible[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
				}
			}

			if ( g_vars->visuals.show_team && player.m_is_teammate )
			{
				ImColor teammate = ImColor( g_vars->colors.teammate_color[ 0 ], g_vars->colors.teammate_color[ 1 ], g_vars->colors.teammate_color[ 2 ] );

				set_box_color = teammate;
				set_text_color = teammate;
				set_arrow_color = teammate;
				set_skeleton_color = teammate;
				set_dot_color = teammate;
				set_arrow_fill_color = teammate;
				set_platform_color = teammate;
				set_rank_color = teammate;
				set_view_angle_color = teammate;
				set_killscore_color = teammate;
				set_teamid_color = teammate;
				set_skeleton_joint_color = teammate;
				set_distance_color = teammate;
				set_username_color = teammate;

				set_fill_color = ImColor( g_vars->colors.teammate_color[ 0 ], g_vars->colors.teammate_color[ 1 ], g_vars->colors.teammate_color[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
			}

			if ( g_vars->visuals.show_dbno && player.is_dbno )
			{
				ImColor knocked = ImColor( g_vars->colors.knocked_color[ 0 ], g_vars->colors.knocked_color[ 1 ], g_vars->colors.knocked_color[ 2 ] );

				set_box_color = knocked;
				set_text_color = knocked;
				set_arrow_color = knocked;
				set_skeleton_color = knocked;
				set_dot_color = knocked;
				set_arrow_fill_color = knocked;
				set_platform_color = knocked;
				set_rank_color = knocked;
				set_view_angle_color = knocked;
				set_killscore_color = knocked;
				set_teamid_color = knocked;
				set_distance_color = knocked;
				set_username_color = knocked;

				set_fill_color = ImColor( g_vars->colors.knocked_color[ 0 ], g_vars->colors.knocked_color[ 1 ], g_vars->colors.knocked_color[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
			}

			if ( g_vars->visuals.mark_enemies && player.m_is_enemy )
			{
				ImColor enemy = ImColor( g_vars->colors.enemy_color[ 0 ], g_vars->colors.enemy_color[ 1 ], g_vars->colors.enemy_color[ 2 ] );

				set_box_color = enemy;
				set_text_color = enemy;
				set_arrow_color = enemy;
				set_skeleton_color = enemy;
				set_dot_color = enemy;
				set_distance_color = enemy;
				set_username_color = enemy;

				set_fill_color = ImColor( g_vars->colors.enemy_color[ 0 ], g_vars->colors.enemy_color[ 1 ], g_vars->colors.enemy_color[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
			}

			if ( g_vars->visuals.mark_friendly && player.m_is_friendly )
			{
				ImColor friendly = ImColor( g_vars->colors.friendly_color[ 0 ], g_vars->colors.friendly_color[ 1 ], g_vars->colors.friendly_color[ 2 ] );

				set_box_color = friendly;
				set_text_color = friendly;
				set_arrow_color = friendly;
				set_skeleton_color = friendly;
				set_dot_color = friendly;
				set_distance_color = friendly;
				set_username_color = friendly;

				set_fill_color = ImColor( g_vars->colors.friendly_color[ 0 ], g_vars->colors.friendly_color[ 1 ], g_vars->colors.friendly_color[ 2 ], g_vars->colors.fill_box_color[ 3 ] );
			}

			if ( g_vars->visuals.boxes || g_vars->visuals.corners || g_vars->visuals.rotating ) {

				set_box_color = g_framework->get_color( set_box_color.Value.x, set_box_color.Value.y, set_box_color.Value.z,
					static_cast< enums::ColorMode >( g_vars->visuals.boxes_mode ), g_vars->ui.rgb_speed );

				set_fill_color = g_framework->get_color( set_fill_color.Value.x, set_fill_color.Value.y, set_fill_color.Value.z,
					static_cast< enums::ColorMode >( g_vars->visuals.boxes_mode ), g_vars->ui.rgb_speed );

				set_fill_color.Value.w = g_vars->colors.fill_box_color[ 3 ];
			}

			if ( g_vars->weapon_config.close_aim.enabled && distance < g_vars->weapon_config.close_aim.distance )
			{
				g_vars->aim.fov_c = g_vars->weapon_config.close_aim.weapon_fov;
				g_vars->aim.smooth = g_vars->weapon_config.close_aim.smooth;
				g_vars->aim.target_bone = g_vars->weapon_config.close_aim.target_bone;
			}

			if ( g_vars->visuals.arrows )
			{
				math::vector3 indicator_on_screen{ };

				auto tracer_angle = atan2(
					head_screen.y - g_render->height_center,
					head_screen.x - g_render->width_center
				);

				auto tracer_offset = g_vars->visuals.arrow_radius;
				auto arrow_width = g_vars->visuals.arrow_widht;

				math::vector3 triangle_end_point = math::vector3(
					g_render->width_center + ( ( tracer_offset + 20 ) * cos( tracer_angle ) ),
					g_render->height_center + ( ( tracer_offset + 20 ) * sin( tracer_angle ) ),
					0
				);

				math::vector3 triangle_second_point = math::vector3(
					g_render->width_center + ( tracer_offset * cos( tracer_angle - ( arrow_width / tracer_offset ) ) ),
					g_render->height_center + ( tracer_offset * sin( tracer_angle - ( arrow_width / tracer_offset ) ) ),
					0
				);

				math::vector3 triangle_final_point = math::vector3(
					g_render->width_center + ( tracer_offset * cos( tracer_angle + ( arrow_width / tracer_offset ) ) ),
					g_render->height_center + ( tracer_offset * sin( tracer_angle + ( arrow_width / tracer_offset ) ) ),
					0
				);

				std::array<math::vector3, 3> points
				{
					math::vector3( triangle_end_point.x, triangle_end_point.y, 0.0f ),
					math::vector3( triangle_second_point.x, triangle_second_point.y, 0.0f ),
					math::vector3( triangle_final_point.x, triangle_final_point.y, 0.0f )
				};

				ImColor arrow_col = g_framework->get_color( set_arrow_color.Value.x, set_arrow_color.Value.y, set_arrow_color.Value.z,
					static_cast< enums::ColorMode >( g_vars->visuals.arrows_mode ), g_vars->ui.rgb_speed );

				ImColor arrow_fill_col = g_framework->get_color( set_arrow_fill_color.Value.x, set_arrow_fill_color.Value.y, set_arrow_fill_color.Value.z,
					static_cast< enums::ColorMode >( g_vars->visuals.arrows_mode ), g_vars->ui.rgb_speed );

				arrow_fill_col.Value.w = g_vars->colors.arrows_filled_color[ 3 ];

				g_framework->triangle(
					ImVec2( points.at( 0 ).x, points.at( 0 ).y ),
					ImVec2( points.at( 1 ).x, points.at( 1 ).y ),
					ImVec2( points.at( 2 ).x, points.at( 2 ).y ),
					arrow_col,
					g_vars->visuals.arrows_outline,
					ImColor( 0, 0, 0 ),
					g_vars->visuals.filled_arrows,
					ImColor( arrow_fill_col.Value.x, arrow_fill_col.Value.y, arrow_fill_col.Value.z, arrow_fill_col.Value.w )
				);
			}

			if ( g_vars->visuals.boxes && player.m_is_on_screen )
			{
				g_framework->bounding_2d(
					math::vector2( player.o.left, player.o.bottom ), math::vector2( player.o.right - player.o.left, player.o.top - player.o.bottom ),
					g_vars->visuals.boxes_thickness,
					set_box_color,
					set_fill_color
				);
			}

			if ( g_vars->visuals.corners && player.m_is_on_screen )
			{
				g_framework->bounding_corner(
					player.o.left, distance_offset, player.o.top, corner_width, player.o.right, player.o.bottom, corner_height,
					g_vars->visuals.boxes_thickness,
					set_box_color,
					set_fill_color
				);
			}

			if ( g_vars->visuals.rotating && player.m_is_on_screen )
			{
				bool should_draw = false;

				math::vector3 player_rotation{};

				engine::frotator rotation = player.rotation;

				player_rotation.x = rotation.Pitch;
				player_rotation.y = rotation.Yaw;
				player_rotation.z = rotation.Roll;

				math::vector3 Right = player_rotation.multiply( { -0.35f, 0.00f, 0.00f } );

				math::vector3 bottomLeft = root_bone - Right;
				math::vector3 bottomLeft2D = g_engine->world_to_screen( bottomLeft );

				math::vector3 bottomRight = root_bone + Right;
				math::vector3 bottomRight2D = g_engine->world_to_screen( bottomRight );

				math::vector3 topLeft = head_bone - Right;
				math::vector3 topLeft2D = g_engine->world_to_screen( topLeft );

				math::vector3 topRight = head_bone + Right;
				math::vector3 topRight2D = g_engine->world_to_screen( topRight );

				should_draw = g_engine->in_screen( bottomLeft2D ) && g_engine->in_screen( bottomRight2D ) && g_engine->in_screen( topLeft2D ) && g_engine->in_screen( topRight2D );

				if ( should_draw )
				{
					g_framework->poly_rect(
						bottomLeft2D,
						bottomRight2D,
						topLeft2D,
						topRight2D,
						g_vars->visuals.boxes_thickness,
						set_box_color,
						set_fill_color
					);
				}
			}

			if ( g_vars->visuals.head_dot && player.m_is_on_screen )
			{
				if ( g_vars->visuals.head_dot_outline ) {
					g_framework->circle( head_screen.x, head_screen.y, g_vars->visuals.head_radius + 0.4f, ImColor( 0, 0, 0 ), 0, g_vars->visuals.head_filled );
				}

				g_framework->circle( head_screen.x, head_screen.y, g_vars->visuals.head_radius, ImColor( g_vars->colors.head_dot_color[ 0 ], g_vars->colors.head_dot_color[ 1 ], g_vars->colors.head_dot_color[ 2 ], g_vars->colors.head_dot_color[ 3 ] ), 0, g_vars->visuals.head_filled );
			}

			if ( g_vars->visuals.skeleton && player.m_is_on_screen )
			{
				auto draw_joint = [ & ]( const math::vector3& position, ImColor color, bool outline ) -> void
					{
						if ( outline ) {
							g_framework->circle( position.x, position.y, g_vars->visuals.skeleton_joints_radius + 0.5f, ImColor( 0, 0, 0 ), 0, true );
						}

						g_framework->circle( position.x, position.y, g_vars->visuals.skeleton_joints_radius, color, 0, true );
					};

				ImColor skeleton_color = g_framework->get_color( set_skeleton_color.Value.x, set_skeleton_color.Value.y, set_skeleton_color.Value.z,
					static_cast< enums::ColorMode >( g_vars->visuals.skeleton_mode ), g_vars->ui.rgb_speed );

				std::vector<std::pair<std::uint32_t, std::uint32_t>> bone_pairs =
				{
					{110, 66},   // head to neck
					{66, 7},   // Neck to upper torso
					{38, 9},    // Upper torso to right shoulder
					{9, 10},   // Right shoulder to right elbow
					{38, 39},  // Left shoulder to left elbow
					{10, 11},  // Right elbow to right hand
					{39, 40},  // Left elbow to left hand
					{7, 2},    // Upper torso to lower torso
					{2, 78},   // Lower torso to left hip
					{2, 71},   // Lower torso to right hip
					{78, 79},  // Left hip to left knee
					{79, 82},  // Left knee to left foot
					{71, 72},  // Right hip to right knee
					{72, 75}   // Right knee to right foot
				};

				for ( const auto& [first, second] : bone_pairs )
				{
					auto start = g_engine->get_bone( player.m_mesh->get_current_class(), first );

					auto end = g_engine->get_bone( player.m_mesh->get_current_class(), second );

					auto start_point = g_engine->world_to_screen( start );
					auto end_point = g_engine->world_to_screen( end );

					if ( !start_point.is_valid() || !end_point.is_valid() )
						continue;

					if ( g_vars->visuals.skeleton_outline )
					{
						g_framework->skeleton(
							start_point.x, start_point.y,
							end_point.x, end_point.y,
							ImColor( 0, 0, 0 ),
							g_vars->visuals.skeleton_outline_thickness
						);
					}

					g_framework->skeleton(
						start_point.x, start_point.y,
						end_point.x, end_point.y,
						skeleton_color,
						g_vars->visuals.skeleton_thickness
					);

					if ( g_vars->visuals.skeleton_joints && distance < 40 )
					{
						draw_joint( start_point, set_skeleton_joint_color, g_vars->visuals.skeleton_joints_outline );
						draw_joint( end_point, set_skeleton_joint_color, g_vars->visuals.skeleton_joints_outline );
					}
				}
			}

			if ( g_vars->visuals.weapon && player.m_is_on_screen )
			{
				ImColor set_weapon_color;

				if ( g_vars->visuals.weapon_tier_color )
					set_weapon_color = get_weapon_color( player.m_weapon_info.m_tier );
				else
					set_weapon_color = ImColor( g_vars->colors.weapon_color[ 0 ], g_vars->colors.weapon_color[ 1 ], g_vars->colors.weapon_color[ 2 ] );

				std::string weapon_name = player.m_weapon_info.m_name.empty() ? hash_str( "Harvesting Tool" ) : player.m_weapon_info.m_name;
				std::string tier_name = g_vars->visuals.weapon_tier_name ? " (" + get_weapon_tier_name( player.m_weapon_info.m_tier ) + ")" : "";
				std::string weapon_ammo = g_vars->visuals.weapon_ammo ? " (" + std::to_string( player.m_weapon_info.m_ammo_count ) + ")" : "";

				std::string combined = weapon_name + tier_name + weapon_ammo;

				ImVec2 text_size = ImGui::CalcTextSize( combined.c_str(), combined.c_str() + combined.size() );

				g_framework->text(
					combined,
					ImVec2( bottom_middle_offset.x - ( text_size.x / 2 ), player.o.bottom + bottom_offset_bounding ),
					set_weapon_color,
					g_vars->font.size,
					g_framework->esp_font
				);

				bottom_offset_bounding += g_vars->font.size;

				if ( g_vars->visuals.weapon_icon )
				{
					std::string weapon_icon{};

					switch ( player.m_weapon_info.animation_type )
					{
					case EFortWeaponCoreAnimation::AssaultRifle:
					case EFortWeaponCoreAnimation::Rifle:
					case EFortWeaponCoreAnimation::AR_DrumGun:
					case EFortWeaponCoreAnimation::AR_ForwardGrip:
					case EFortWeaponCoreAnimation::AR_BullPup:
						weapon_icon = hash_str( "rifle.ak" );
						break;

					case EFortWeaponCoreAnimation::Shotgun:
					case EFortWeaponCoreAnimation::TacticalShotgun:
						weapon_icon = hash_str( "shotgun.pump" );
						break;

					case EFortWeaponCoreAnimation::SniperRifle:
						weapon_icon = hash_str( "rifle.bolt" );
						break;

					case EFortWeaponCoreAnimation::MachinePistol:
					case EFortWeaponCoreAnimation::SMG_P90:
					case EFortWeaponCoreAnimation::Pistol:
						weapon_icon = hash_str( "smg.mp5" );
						break;

					case EFortWeaponCoreAnimation::Consumable_Small:
					case EFortWeaponCoreAnimation::MeleeDualWield:
						weapon_icon = hash_str( "syringe.medical" );
						break;

					default:
						weapon_icon = hash_str( "unknown" );
						break;
					}

					auto data = g_icons->get_icon_data( weapon_icon );

					ImVec2 position( bottom_middle_offset.x, player.o.bottom + bottom_offset_bounding );

					ImVec2 icon_position( position.x - ( data.icon_size.x / 2 ), position.y );
					ImVec2 bottom_right_rect( icon_position.x + data.icon_size.x, icon_position.y + data.icon_size.y );

					if ( data.texture )
					{
						g_framework->add_image( data.texture, icon_position, bottom_right_rect, ImColor( 255, 255, 255 ) );

						bottom_offset_bounding += data.icon_size.y;
					}
				}
			}

			if ( g_vars->visuals.team && player.m_team_index > 0 && player.m_is_on_screen )
			{
				std::string player_team = hash_str( "Team " ) + std::to_string( player.m_team_index );
				ImVec2 text_size = ImGui::CalcTextSize( player_team.c_str() );

				g_framework->text(
					player_team,
					ImVec2( bottom_middle_offset.x - ( text_size.x / 2 ), player.o.bottom + bottom_offset_bounding ),
					set_teamid_color,
					g_vars->font.size,
					g_framework->esp_font
				);

				bottom_offset_bounding += g_vars->font.size;
			}

			if ( g_vars->visuals.kill_count && player.m_kill_count > 0 && player.m_is_on_screen )
			{
				std::string kill_score = hash_str( "Kills " ) + std::to_string( player.m_kill_count );
				ImVec2 text_size = ImGui::CalcTextSize( kill_score.c_str() );

				g_framework->text(
					kill_score,
					ImVec2( bottom_middle_offset.x - ( text_size.x / 2 ), player.o.bottom + bottom_offset_bounding ),
					set_killscore_color,
					g_vars->font.size,
					g_framework->esp_font
				);

				bottom_offset_bounding += g_vars->font.size;
			}

			if ( ( g_vars->visuals.username || g_vars->visuals.distance ) && player.m_is_on_screen )
			{
				std::string username = player.m_username;
				std::string distance_text = std::to_string( distance ) + hash_str( "m" );

				ImVec2 username_size = ImGui::CalcTextSize( username.c_str() );
				ImVec2 distance_size = ImGui::CalcTextSize( distance_text.c_str() );

				float padding = 2.0f;

				float combined_width = g_vars->visuals.username && g_vars->visuals.distance
					? username_size.x + padding + distance_size.x
					: ( g_vars->visuals.username ? username_size.x : distance_size.x );

				float centered_x = bottom_middle_offset.x - ( combined_width / 2 );

				ImVec2 username_position = g_vars->visuals.username
					? ImVec2( centered_x, player.o.top - top_offset_bounding )
					: ImVec2( 0, 0 );

				ImVec2 distance_position = g_vars->visuals.distance
					? ImVec2(
						centered_x + ( g_vars->visuals.username ? username_size.x + padding : 0 ),
						player.o.top - top_offset_bounding )
					: ImVec2( 0, 0 );

				if ( g_vars->visuals.username )
				{
					g_framework->text(
						username,
						username_position,
						set_username_color,
						g_vars->font.size,
						g_framework->esp_font
					);
				}

				if ( g_vars->visuals.distance )
				{
					g_framework->text(
						distance_text,
						distance_position,
						set_distance_color,
						g_vars->font.size,
						g_framework->esp_font
					);
				}

				top_offset_bounding += g_vars->font.size;
			}

			if ( g_vars->visuals.platform && player.m_is_on_screen && !is_bot )
			{
				if ( g_vars->visuals.platform_text )
				{
					set_platform_color = parse_platformcolor( player.m_platform );

					std::string player_platform = player.m_platform;
					ImVec2 text_size = ImGui::CalcTextSize( player_platform.c_str() );

					g_framework->text(
						player_platform,
						ImVec2( bottom_middle_offset.x - ( text_size.x / 2 ), player.o.top - top_offset_bounding ),
						set_platform_color,
						g_vars->font.size,
						g_framework->esp_font
					);

					top_offset_bounding += g_vars->font.size;
				}

				if ( g_vars->visuals.platform_icon )
				{
					auto data = g_icons->get_icon_data( player.m_platform );

					ImVec2 position( bottom_middle_offset.x, player.o.top - top_offset_bounding - padding_text );

					ImVec2 icon_position( position.x - ( data.icon_size.x / 2 ), position.y - ( data.icon_size.y / 2 ) );
					ImVec2 bottom_right_rect( icon_position.x + data.icon_size.x, icon_position.y + data.icon_size.y );

					if ( data.texture ) {
						g_framework->add_image( data.texture, icon_position, bottom_right_rect, ImColor( 255, 255, 255 ) );

						top_offset_bounding += padding_text + data.icon_size.y;
					}
				}
			}

			if ( g_vars->visuals.rank && player.m_is_on_screen && !is_bot )
			{
				if ( g_vars->visuals.rank_text )
				{
					if ( g_vars->visuals.rank_tier_color )
						set_rank_color = parse_rankcolor( player.m_rank_information.Rank );

					std::string rank_name = parse_rank( player.m_rank_information.Rank );
					ImVec2 text_size = ImGui::CalcTextSize( rank_name.c_str() );

					g_framework->text(
						rank_name,
						ImVec2( bottom_middle_offset.x - ( text_size.x / 2 ), player.o.top - top_offset_bounding ),
						set_rank_color,
						g_vars->font.size,
						g_framework->esp_font
					);

					top_offset_bounding += g_vars->font.size;
				}

				if ( g_vars->visuals.rank_icon )
				{
					auto data = g_icons->get_icon_data( parse_rank( player.m_rank_information.Rank ) );

					ImVec2 position( bottom_middle_offset.x, player.o.top - top_offset_bounding - padding_text );

					ImVec2 icon_position( position.x - ( data.icon_size.x / 2 ), position.y - ( data.icon_size.y / 2 ) );
					ImVec2 bottom_right_rect( icon_position.x + data.icon_size.x, icon_position.y + data.icon_size.y );

					if ( data.texture ) {
						g_framework->add_image( data.texture, icon_position, bottom_right_rect, ImColor( 255, 255, 255 ) );

						top_offset_bounding += padding_text + data.icon_size.y;
					}
				}
			}

			//if ( g_vars->visuals.flags && player.m_is_on_screen )
			//{
			//	std::vector<std::string> PlayerFlags{};

			//	if ( g_vars->flags.wounded && player.is_dbno )
			//		PlayerFlags.push_back( hash_str( "K" ) );

			//	if ( g_vars->flags.reloading && player.m_weapon_info.m_reloading )
			//		PlayerFlags.push_back( hash_str( "R" ) );

			//	if ( g_vars->flags.crouched && player.m_movement.m_is_crouched )
			//		PlayerFlags.push_back( hash_str( "C" ) );

			//	if ( g_vars->flags.falling && player.m_movement.m_is_falling )
			//		PlayerFlags.push_back( hash_str( "F" ) );

			//	if ( g_vars->flags.flying && player.m_movement.m_is_flying )
			//		PlayerFlags.push_back( hash_str( "FL" ) );

			//	if ( g_vars->flags.idle && player.m_movement.m_is_idle )
			//		PlayerFlags.push_back( hash_str( "A" ) );

			//	if ( g_vars->flags.swimming && player.m_movement.m_is_swimming )
			//		PlayerFlags.push_back( hash_str( "S" ) );

			//	if ( g_vars->flags.walking && player.m_movement.m_is_walking )
			//		PlayerFlags.push_back( hash_str( "W" ) );

			//	auto total_flags_spacing = 0.00f;

			//	for ( const auto& Flag : PlayerFlags )
			//	{
			//		g_framework->text(
			//			Flag,
			//			ImVec2( player.o.right + 10.00f, player.o.top - total_flags_spacing ),
			//			set_text_color,
			//			g_vars->font.size,
			//			g_framework->esp_font
			//		);

			//		total_flags_spacing += g_vars->font.size;
			//	}
			//}

			if ( g_vars->visuals.snapline && player.m_is_on_screen )
			{
				auto should_draw = true;

				if ( g_vars->visuals.show_only_visible_snaplines && !player.is_visible )
					should_draw = false;

				if ( should_draw )
				{
					auto color = g_framework->get_color( g_vars->colors.snapline_color[ 0 ], g_vars->colors.snapline_color[ 1 ], g_vars->colors.snapline_color[ 2 ],
						static_cast< enums::ColorMode >( g_vars->visuals.snapline_mode ), g_vars->ui.rgb_speed );

					auto end_point = g_vars->visuals.snapline_end ? ImVec2( head_screen.x, head_screen.y ) : ImVec2( root_screen.x, root_screen.y );

					if ( g_vars->visuals.snapline_outline )
						g_framework->line( ImVec2( g_vars->visuals.snapline_x, g_vars->visuals.snapline_y ), end_point, ImColor( 0, 0, 0 ), 1.4f );

					g_framework->line( ImVec2( g_vars->visuals.snapline_x, g_vars->visuals.snapline_y ), end_point, color, 1.f );
				}
			}

			if ( g_vars->visuals.view_direction && player.m_is_on_screen )
			{
				math::vector3 player_rotation{};

				engine::frotator rotation = player.rotation;

				player_rotation.x = rotation.Pitch *= g_vars->misc.eye_tracer_length;
				player_rotation.y = rotation.Yaw *= g_vars->misc.eye_tracer_length;
				player_rotation.z = rotation.Roll *= g_vars->misc.eye_tracer_length;

				math::vector3 to = head_bone + player_rotation;
				math::vector3 head_rotation = g_engine->world_to_screen( to );

				g_framework->line(
					ImVec2( head_screen.x, head_screen.y + 7.0f ),
					ImVec2( head_rotation.x, head_rotation.y ),
					set_view_angle_color,
					1.5f
				);
			}

			if ( g_vars->visuals.radar )
			{
				auto do_radar = [ & ]() -> void
					{
						float radius = 3.00f;
						ImVec2 projection = ImVec2();

						g_engine->calculate_radar_point(
							head_bone,
							projection.x,
							projection.y,
							ImVec2( g_vars->radar.radar_width, g_vars->radar.radar_height )
						);

						if ( distance > g_vars->radar.radar_distance ) return;

						if ( g_vars->radar.ignore_teammates && player.m_is_teammate ) return;

						if ( g_vars->radar.ignore_wounded && player.is_dbno ) return;

						if ( g_vars->radar.ignore_invisible && !player.is_visible ) return;

						g_framework->render_radar_object(
							projection,
							radius,
							set_dot_color,
							g_vars->radar.outlined_dots,
							g_vars->radar.display_distance,
							distance
						);
					};

				do_radar();
			}
		}

		g_aimbot->closest_actor = closest_player;

		if ( closest_player.m_actor )
		{
			if ( g_vars->visuals.mark_friendly && GetAsyncKeyState( g_vars->visuals.mark_friendly_bind ) ) {

				if ( friendly_map[ closest_player.m_actor ] == true ) {
					friendly_map[ closest_player.m_actor ] = false;
				}
				else {
					friendly_map[ closest_player.m_actor ] = true;
					enemy_map[ closest_player.m_actor ] = false;
				}
			}
			else if ( g_vars->visuals.mark_enemies && GetAsyncKeyState( g_vars->visuals.mark_enemies_bind ) ) {

				if ( enemy_map[ closest_player.m_actor ] == true ) {
					enemy_map[ closest_player.m_actor ] = false;
				}
				else {
					friendly_map[ closest_player.m_actor ] = false;
					enemy_map[ closest_player.m_actor ] = true;
				}
			}
		}

	}
	catch ( const std::exception& e ) {
		m_log->set_text_point( hash_str( "exception caught in entity render thread" ) );
		return;
	}
	catch ( ... ) {
		m_log->set_text_point( hash_str( "exception caught in entity render thread" ) );
		return;
	}
}

#endif