-
Автор темы
- #1
Как оказалось, это было не сложно...
Но тут нет фиксов которые нужны)) Поэтому, держите
Но тут нет фиксов которые нужны)) Поэтому, держите
Код:
void clamp_bones_in_bbox(c_cs_player* player, matrix3x4_t* matrix, int mask, float curtime) {
auto hdr = player->get_studio_hdr();
if (!hdr)
return;
auto head_bone = player->lookup_bone(XOR("head_0"));
if (head_bone < 0)
return;
auto collideable = player->get_collideable();
if (!collideable)
return;
auto collision_origin = collideable->get_collision_origin().z;
auto bbox_max = collideable->get_maxs().z + collision_origin;
auto last_update_increment = curtime - player->collision_change_time();
if (last_update_increment < 0.2f) {
auto approach_time = std::clamp<float>(last_update_increment * 5.f, 0.f, 1.f);
bbox_max = ((bbox_max - player->collision_change_origin()) * approach_time) + player->collision_change_origin();
}
auto head_bone_origin = matrix[head_bone].get_origin();
vec3_t pos{}, forward{}, right{}, up{};
__patterns->weapon_shootpos.cast<float* (__thiscall*)(void*, vec3_t*)>()(player, &pos);
math::angle_vectors(player->eye_angles(), forward, right, up);
auto head_pos_diff = (((right.x * head_bone_origin.x) + (right.y * head_bone_origin.y))
+ (right.z * head_bone_origin.z))
- (((head_bone_origin.y * right.y) + (head_bone_origin.x * right.x)) + (head_bone_origin.z * right.z));
vec3_t new_bone_pos{};
if (std::fabsf(head_pos_diff) <= 3.f) {
new_bone_pos = head_bone_origin;
}
else {
auto unk_multiplier = 0.f;
if (head_pos_diff < 0.f)
unk_multiplier = -1.0;
else
unk_multiplier = 1.0;
auto unk_vector = (right - forward).normalized();
auto updated_pos_z = (unk_vector.z * 3.f) * unk_multiplier;
auto updated_pos_y = (unk_vector.x * 3.f) * unk_multiplier;
auto updated_pos_x = (unk_vector.y * 3.f) * unk_multiplier;
auto v21 = head_bone_origin.x - (right.x * head_pos_diff);
auto v22 = head_bone_origin.y - (right.y * head_pos_diff);
new_bone_pos.z = (head_bone_origin.z - (right.z * head_pos_diff)) + updated_pos_z;
new_bone_pos.x = v21 + updated_pos_y;
new_bone_pos.y = v22 + updated_pos_x;
}
if (new_bone_pos.z > (bbox_max - 4.f))
new_bone_pos.z = bbox_max - 4.f;
auto clamped_bones_new = vec3_t{ new_bone_pos.x - pos.x, new_bone_pos.y - pos.y, 0.f };
if (clamped_bones_new.length() > 11.f) {
auto normalized = (clamped_bones_new - forward).normalized();
new_bone_pos.x = (normalized.x * 11.f) + pos.x;
new_bone_pos.y = (normalized.y * 11.f) + pos.y;
}
auto pos_diff = head_bone_origin - new_bone_pos;
if (pos_diff.valid() && pos_diff.length() < 900.f) {
auto ankle_l_bone = player->lookup_bone(XOR("ankle_L"));
auto ankle_r_bone = player->lookup_bone(XOR("ankle_R"));
auto deref_hdr = *reinterpret_cast<std::uintptr_t*>(hdr);
auto bone_chains = *(int*)(deref_hdr + 0x11C);
if (bone_chains > 0) {
auto ik_chain_ptr = deref_hdr + *(int*)(deref_hdr + 0x120);
auto left_chain = 0, right_chain = 0;
for (int i = 0; i < bone_chains; ++i) {
auto current_chain_index = *(int*)(*(int*)(ik_chain_ptr + 12) + ik_chain_ptr + 56);
if (ankle_l_bone == current_chain_index)
left_chain = ik_chain_ptr;
else if (ankle_r_bone == current_chain_index)
right_chain = ik_chain_ptr;
if (left_chain && right_chain)
break;
ik_chain_ptr += 16;
}
auto ankle_l_pos = matrix[ankle_l_bone].get_origin();
auto ankle_r_pos = matrix[ankle_r_bone].get_origin();
auto legs_pos = std::min<float>(ankle_l_pos.z, ankle_r_pos.z);
auto lookup_spine_3 = player->lookup_bone(XOR("spine_3"));
auto unk_counter_hdr = *(int*)(deref_hdr + 0x9C);
auto ground_entity = player->ground_entity().get().cast<c_base_entity*>();
bool solve_ik_left = false;
bool solve_ik_right = false;
if (unk_counter_hdr > 0) {
for (int i = 0; i < unk_counter_hdr; ++i) {
auto& bone = matrix[i];
auto bone_origin = bone.get_origin();
auto unk_hdr_pointer = *(int*)((uintptr_t)hdr + 48);
auto bone_mask = *(int*)(unk_hdr_pointer + 4 * i);
if (!(bone_mask & mask))
continue;
if (i == ankle_l_bone && left_chain && ground_entity) {
solve_ik_left = true;
continue;
}
else if (i == ankle_r_bone && right_chain && ground_entity) {
solve_ik_right = true;
continue;
}
float head_adjust = 1.0f;
// credits: @william to this part
if (ground_entity) {
auto bone_parent_count = *(int*)((uintptr_t)hdr + 80);
auto second_bone_iter = 0;
if (bone_parent_count > 0 && i >= 0 && lookup_spine_3 >= 0) {
auto studio_hdr_mat_iter = *(int*)((uintptr_t)hdr + 0x44);
second_bone_iter = *(int*)(studio_hdr_mat_iter + 4 * i);
while (second_bone_iter != lookup_spine_3 && second_bone_iter != -1)
second_bone_iter = *(int*)(studio_hdr_mat_iter + 4 * second_bone_iter);
}
if (second_bone_iter == -1) {
const float diff_correction = bone_origin.z - (head_bone_origin.z - pos_diff.z);
if (legs_pos == bone_origin.z) {
if (diff_correction - bone_origin.z >= 0.0f)
head_adjust = 1.0f;
else
head_adjust = 0.0f;
}
else {
const float new_head_adjust = (diff_correction - legs_pos) / (bone_origin.z - legs_pos);
if (new_head_adjust < 0.0f)
head_adjust = 0.0f;
else
head_adjust = fminf(new_head_adjust, 1.0f);
}
}
}
bone_origin -= (pos_diff * head_adjust);
bone.set_origin(bone_origin);
}
if (solve_ik_left) {
auto link_a = *(int*)(*(int*)(left_chain + 12) + left_chain + 28);
auto link_b = *(int*)(*(int*)(left_chain + 12) + left_chain);
Studio_SolveIK(player, link_a, link_b, ankle_l_bone, ankle_l_pos, matrix);
}
if (solve_ik_right) {
auto link_a = *(int*)(*(int*)(right_chain + 12) + left_chain + 28);
auto link_b = *(int*)(*(int*)(right_chain + 12) + left_chain);
Studio_SolveIK(player, link_a, link_b, ankle_r_bone, ankle_r_pos, matrix);
}
}
}
}
}
// module: client.dll; sig 53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 83 EC 48 56 8D
void Studio_SolveIK(c_cs_player* player, int thigh, int knee, int foot, vec3_t& target_foot, matrix3x4_t* bone_to_world) {
__patterns->studio_solve_ik.cast<bool*(__thiscall)(c_cs_player*, int, int, int, vec3_t&, matrix3x4_t*)>()(player, thigh, knee, target_foot, bone_to_world);
}