void Visuals::DrawSkeleton(Player* player, int opacity) {
const model_t* model;
studiohdr_t* hdr;
mstudiobone_t* bone;
int parent;
Color color;
BoneArray matrix[256];
vec3_t bone_pos, parent_pos;
vec2_t bone_pos_screen, parent_pos_screen;
// get player's model.
model = player->GetModel();
if (!model)
return;
// get studio model.
hdr = g_csgo.m_model_info->GetStudioModel(model);
if (!hdr)
return;
// get bone matrix.
if (!player->SetupBones(matrix, 256, BONE_USED_BY_ANYTHING, g_csgo.m_globals->m_curtime))
return;
// is player local.
bool local = player->m_bIsLocalPlayer();
// is player enemy.
bool enemy = player->enemy(g_cl.m_local);
// get color.
if (enemy && !local)
color = g_config.imcolor_to_ccolor(g_config.c[XOR("visuals_player_esp_enemy_skeleton_col")]);
else if (!local)
color = g_config.imcolor_to_ccolor(g_config.c[XOR("visuals_player_esp_friendly_skeleton_col")]);
else
color = g_config.imcolor_to_ccolor(g_config.c[XOR("visuals_player_esp_local_skeleton_col")]);
color.a() = opacity;
for (int i{ }; i < hdr->m_num_bones; ++i)
{
// get bone.
bone = hdr->GetBone(i);
if (!bone || !(bone->m_flags & BONE_USED_BY_HITBOX))
continue;
// get parent bone.
parent = bone->m_parent;
if (parent == -1)
continue;
// resolve main bone and parent bone positions.
matrix->get_bone(bone_pos, i);
matrix->get_bone(parent_pos, parent);
// world to screen both the bone parent bone then draw.
if (render::WorldToScreen(bone_pos, bone_pos_screen) && render::WorldToScreen(parent_pos, parent_pos_screen))
render::line(bone_pos_screen.x, bone_pos_screen.y, parent_pos_screen.x, parent_pos_screen.y, color);
}
}