float thirdperson_distance = 0.0f;
void thirdperson()
{
if (!g_local)
return;
if (!g_local->is_alive())
{
i::input->camera_in_thirdperson = false;
thirdperson_distance = 50.0f;
g_local->m_iObserverMode() = 5 /*obs_mode_chase*/;
return;
}
bool is_enabled = g_bind[bind_third_person].active;
if (is_enabled)
thirdperson_distance = std::min(std::max(thirdperson_distance, 30.0f) + 6.0f, (float)g_vars.visuals.third_person_distace);
else
thirdperson_distance = std::max(thirdperson_distance - 6.0f, 30.0f);
if (thirdperson_distance <= (is_enabled ? 50.0f : 30.0f))
{
i::input->camera_in_thirdperson = false;
return;
}
vec3_t eyepos = g_local->get_abs_origin() + g_local->m_vecViewOffset();
if (g::fake_ducking)
eyepos = g_local->get_abs_origin() + i::game_movement->get_player_view_offset(false);
vec3_t viewangles;
i::engine->get_viewangles(viewangles);
i::input->camera_in_thirdperson = true;
i::input->camera_offset = vec3_t(viewangles.x, viewangles.y, thirdperson_distance);
trace_t trace;
float extent = 12.f + (thirdperson_distance / 4.8f - 18.f);
vec3_t forward = vec3_t(0, 0, 0);
math::angle_vectors(vec3_t(viewangles.x, viewangles.y, 0.0f), forward);
trace_hull(eyepos, eyepos - forward * i::input->camera_offset.z, mask_solid & ~contents_monster, vec3_t(extent, extent, extent), &trace);
i::input->camera_offset.z *= trace.fraction;
if (i::input->camera_offset.z < std::min(30.0f, (float)g_vars.visuals.third_person_distace))
i::input->camera_in_thirdperson = false;
}
void __fastcall hooks::clientmode::override_view::hook( void* ecx, void* edx, view_setup_t* view ) {
if ( !i::engine->is_in_game( ) || !g_local ) {
o_override_view( ecx, edx, view );
return;
}
thirdperson();
o_override_view( ecx, edx, view );
return;
}